Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 78105
b: refs/heads/master
c: 862b82c
h: refs/heads/master
i:
  78103: 50c848c
v: v3
  • Loading branch information
Herbert Xu authored and David S. Miller committed Jan 28, 2008
1 parent 977d9ca commit 0bf6587
Show file tree
Hide file tree
Showing 12 changed files with 89 additions and 146 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ef76bc23ef2acf20c8f7f841a542d8ab74c827c6
refs/heads/master: 862b82c6f960cc61274d370aa78ce1112f92a83e
1 change: 1 addition & 0 deletions trunk/include/net/dst.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct dst_ops
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
int (*local_out)(struct sk_buff *skb);
int entry_size;

atomic_t entries;
Expand Down
1 change: 1 addition & 0 deletions trunk/include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@ struct xfrm_state_afinfo {
unsigned int family;
unsigned int proto;
unsigned int eth_proto;
unsigned int nf_post_routing;
struct module *owner;
struct xfrm_type *type_map[IPPROTO_MAX];
struct xfrm_mode *mode_map[XFRM_MODE_MAX];
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ static struct dst_ops ipv4_dst_ops = {
.negative_advice = ipv4_negative_advice,
.link_failure = ipv4_link_failure,
.update_pmtu = ip_rt_update_pmtu,
.local_out = ip_local_out,
.entry_size = sizeof(struct rtable),
};

Expand Down
76 changes: 4 additions & 72 deletions trunk/net/ipv4/xfrm4_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,95 +59,27 @@ int xfrm4_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
return err;

memset(IPCB(skb), 0, sizeof(*IPCB(skb)));
IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE;
IPCB(skb)->flags |= IPSKB_XFRM_TUNNEL_SIZE | IPSKB_XFRM_TRANSFORMED;

skb->protocol = htons(ETH_P_IP);

return x->outer_mode->output2(x, skb);
}
EXPORT_SYMBOL(xfrm4_prepare_output);

static inline int xfrm4_output_one(struct sk_buff *skb)
{
int err;

err = xfrm_output(skb);
if (err)
goto error_nolock;

IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
err = 0;

out_exit:
return err;
error_nolock:
kfree_skb(skb);
goto out_exit;
}

static int xfrm4_output_finish2(struct sk_buff *skb)
{
int err;

while (likely((err = xfrm4_output_one(skb)) == 0)) {
nf_reset(skb);

err = __ip_local_out(skb);
if (unlikely(err != 1))
break;

if (!skb->dst->xfrm)
return dst_output(skb);

err = nf_hook(PF_INET, NF_IP_POST_ROUTING, skb, NULL,
skb->dst->dev, xfrm4_output_finish2);
if (unlikely(err != 1))
break;
}

return err;
}

static int xfrm4_output_finish(struct sk_buff *skb)
{
struct sk_buff *segs;

#ifdef CONFIG_NETFILTER
if (!skb->dst->xfrm) {
IPCB(skb)->flags |= IPSKB_REROUTED;
return dst_output(skb);
}
#endif

if (!skb_is_gso(skb))
return xfrm4_output_finish2(skb);
IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED;
#endif

skb->protocol = htons(ETH_P_IP);
segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
if (unlikely(IS_ERR(segs)))
return PTR_ERR(segs);

do {
struct sk_buff *nskb = segs->next;
int err;

segs->next = NULL;
err = xfrm4_output_finish2(segs);

if (unlikely(err)) {
while ((segs = nskb)) {
nskb = segs->next;
segs->next = NULL;
kfree_skb(segs);
}
return err;
}

segs = nskb;
} while (segs);

return 0;
return xfrm_output(skb);
}

int xfrm4_output(struct sk_buff *skb)
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv4/xfrm4_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,7 @@ static struct dst_ops xfrm4_dst_ops = {
.update_pmtu = xfrm4_update_pmtu,
.destroy = xfrm4_dst_destroy,
.ifdown = xfrm4_dst_ifdown,
.local_out = __ip_local_out,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
};
Expand Down
2 changes: 2 additions & 0 deletions trunk/net/ipv4/xfrm4_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <net/xfrm.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
#include <linux/netfilter_ipv4.h>

static struct xfrm_state_afinfo xfrm4_state_afinfo;

Expand Down Expand Up @@ -66,6 +67,7 @@ static struct xfrm_state_afinfo xfrm4_state_afinfo = {
.family = AF_INET,
.proto = IPPROTO_IPIP,
.eth_proto = htons(ETH_P_IP),
.nf_post_routing = NF_IP_POST_ROUTING,
.owner = THIS_MODULE,
.init_flags = xfrm4_init_flags,
.init_tempsel = __xfrm4_init_tempsel,
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static struct dst_ops ip6_dst_ops = {
.negative_advice = ip6_negative_advice,
.link_failure = ip6_link_failure,
.update_pmtu = ip6_rt_update_pmtu,
.local_out = ip6_local_out,
.entry_size = sizeof(struct rt6_info),
};

Expand Down
77 changes: 7 additions & 70 deletions trunk/net/ipv6/xfrm6_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,87 +66,24 @@ int xfrm6_prepare_output(struct xfrm_state *x, struct sk_buff *skb)
return err;

memset(IP6CB(skb), 0, sizeof(*IP6CB(skb)));
#ifdef CONFIG_NETFILTER
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
#endif

skb->protocol = htons(ETH_P_IPV6);

return x->outer_mode->output2(x, skb);
}
EXPORT_SYMBOL(xfrm6_prepare_output);

static inline int xfrm6_output_one(struct sk_buff *skb)
{
int err;

err = xfrm_output(skb);
if (err)
goto error_nolock;

IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
err = 0;

out_exit:
return err;
error_nolock:
kfree_skb(skb);
goto out_exit;
}

static int xfrm6_output_finish2(struct sk_buff *skb)
{
int err;

while (likely((err = xfrm6_output_one(skb)) == 0)) {
nf_reset(skb);

err = __ip6_local_out(skb);
if (unlikely(err != 1))
break;

if (!skb->dst->xfrm)
return dst_output(skb);

err = nf_hook(PF_INET6, NF_IP6_POST_ROUTING, skb, NULL,
skb->dst->dev, xfrm6_output_finish2);
if (unlikely(err != 1))
break;
}

return err;
}

static int xfrm6_output_finish(struct sk_buff *skb)
{
struct sk_buff *segs;

if (!skb_is_gso(skb))
return xfrm6_output_finish2(skb);
#ifdef CONFIG_NETFILTER
IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED;
#endif

skb->protocol = htons(ETH_P_IPV6);
segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
if (unlikely(IS_ERR(segs)))
return PTR_ERR(segs);

do {
struct sk_buff *nskb = segs->next;
int err;

segs->next = NULL;
err = xfrm6_output_finish2(segs);

if (unlikely(err)) {
while ((segs = nskb)) {
nskb = segs->next;
segs->next = NULL;
kfree_skb(segs);
}
return err;
}

segs = nskb;
} while (segs);

return 0;
return xfrm_output(skb);
}

int xfrm6_output(struct sk_buff *skb)
Expand Down
1 change: 1 addition & 0 deletions trunk/net/ipv6/xfrm6_policy.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,7 @@ static struct dst_ops xfrm6_dst_ops = {
.update_pmtu = xfrm6_update_pmtu,
.destroy = xfrm6_dst_destroy,
.ifdown = xfrm6_dst_ifdown,
.local_out = __ip6_local_out,
.gc_thresh = 1024,
.entry_size = sizeof(struct xfrm_dst),
};
Expand Down
2 changes: 2 additions & 0 deletions trunk/net/ipv6/xfrm6_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <net/xfrm.h>
#include <linux/pfkeyv2.h>
#include <linux/ipsec.h>
#include <linux/netfilter_ipv6.h>
#include <net/dsfield.h>
#include <net/ipv6.h>
#include <net/addrconf.h>
Expand Down Expand Up @@ -189,6 +190,7 @@ static struct xfrm_state_afinfo xfrm6_state_afinfo = {
.family = AF_INET6,
.proto = IPPROTO_IPV6,
.eth_proto = htons(ETH_P_IPV6),
.nf_post_routing = NF_IP6_POST_ROUTING,
.owner = THIS_MODULE,
.init_tempsel = __xfrm6_init_tempsel,
.tmpl_sort = __xfrm6_tmpl_sort,
Expand Down
70 changes: 67 additions & 3 deletions trunk/net/xfrm/xfrm_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <linux/errno.h>
#include <linux/module.h>
#include <linux/netdevice.h>
#include <linux/netfilter.h>
#include <linux/skbuff.h>
#include <linux/spinlock.h>
#include <net/dst.h>
Expand Down Expand Up @@ -40,7 +41,7 @@ static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
return err;
}

int xfrm_output(struct sk_buff *skb)
static int xfrm_output_one(struct sk_buff *skb)
{
struct dst_entry *dst = skb->dst;
struct xfrm_state *x = dst->xfrm;
Expand Down Expand Up @@ -87,10 +88,73 @@ int xfrm_output(struct sk_buff *skb)

err = 0;

error_nolock:
out_exit:
return err;
error:
spin_unlock_bh(&x->lock);
goto error_nolock;
error_nolock:
kfree_skb(skb);
goto out_exit;
}

static int xfrm_output2(struct sk_buff *skb)
{
int err;

while (likely((err = xfrm_output_one(skb)) == 0)) {
struct xfrm_state *x;

nf_reset(skb);

err = skb->dst->ops->local_out(skb);
if (unlikely(err != 1))
break;

x = skb->dst->xfrm;
if (!x)
return dst_output(skb);

err = nf_hook(x->inner_mode->afinfo->family,
x->inner_mode->afinfo->nf_post_routing, skb,
NULL, skb->dst->dev, xfrm_output2);
if (unlikely(err != 1))
break;
}

return err;
}

int xfrm_output(struct sk_buff *skb)
{
struct sk_buff *segs;

if (!skb_is_gso(skb))
return xfrm_output2(skb);

segs = skb_gso_segment(skb, 0);
kfree_skb(skb);
if (unlikely(IS_ERR(segs)))
return PTR_ERR(segs);

do {
struct sk_buff *nskb = segs->next;
int err;

segs->next = NULL;
err = xfrm_output2(segs);

if (unlikely(err)) {
while ((segs = nskb)) {
nskb = segs->next;
segs->next = NULL;
kfree_skb(segs);
}
return err;
}

segs = nskb;
} while (segs);

return 0;
}
EXPORT_SYMBOL_GPL(xfrm_output);

0 comments on commit 0bf6587

Please sign in to comment.