OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [net/] [xfrm/] [xfrm_output.c] - Blame information for rev 67

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 * xfrm_output.c - Common IPsec encapsulation code.
3
 *
4
 * Copyright (c) 2007 Herbert Xu <herbert@gondor.apana.org.au>
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version
9
 * 2 of the License, or (at your option) any later version.
10
 */
11
 
12
#include <linux/errno.h>
13
#include <linux/module.h>
14
#include <linux/netdevice.h>
15
#include <linux/skbuff.h>
16
#include <linux/spinlock.h>
17
#include <net/dst.h>
18
#include <net/xfrm.h>
19
 
20
static int xfrm_state_check_space(struct xfrm_state *x, struct sk_buff *skb)
21
{
22
        int nhead = x->props.header_len + LL_RESERVED_SPACE(skb->dst->dev)
23
                - skb_headroom(skb);
24
 
25
        if (nhead > 0)
26
                return pskb_expand_head(skb, nhead, 0, GFP_ATOMIC);
27
 
28
        /* Check tail too... */
29
        return 0;
30
}
31
 
32
static int xfrm_state_check(struct xfrm_state *x, struct sk_buff *skb)
33
{
34
        int err = xfrm_state_check_expire(x);
35
        if (err < 0)
36
                goto err;
37
        err = xfrm_state_check_space(x, skb);
38
err:
39
        return err;
40
}
41
 
42
int xfrm_output(struct sk_buff *skb)
43
{
44
        struct dst_entry *dst = skb->dst;
45
        struct xfrm_state *x = dst->xfrm;
46
        int err;
47
 
48
        if (skb->ip_summed == CHECKSUM_PARTIAL) {
49
                err = skb_checksum_help(skb);
50
                if (err)
51
                        goto error_nolock;
52
        }
53
 
54
        do {
55
                spin_lock_bh(&x->lock);
56
                err = xfrm_state_check(x, skb);
57
                if (err)
58
                        goto error;
59
 
60
                if (x->type->flags & XFRM_TYPE_REPLAY_PROT) {
61
                        XFRM_SKB_CB(skb)->seq = ++x->replay.oseq;
62
                        if (xfrm_aevent_is_on())
63
                                xfrm_replay_notify(x, XFRM_REPLAY_UPDATE);
64
                }
65
 
66
                err = x->outer_mode->output(x, skb);
67
                if (err)
68
                        goto error;
69
 
70
                x->curlft.bytes += skb->len;
71
                x->curlft.packets++;
72
 
73
                spin_unlock_bh(&x->lock);
74
 
75
                err = x->type->output(x, skb);
76
                if (err)
77
                        goto error_nolock;
78
 
79
                if (!(skb->dst = dst_pop(dst))) {
80
                        err = -EHOSTUNREACH;
81
                        goto error_nolock;
82
                }
83
                dst = skb->dst;
84
                x = dst->xfrm;
85
        } while (x && !(x->outer_mode->flags & XFRM_MODE_FLAG_TUNNEL));
86
 
87
        err = 0;
88
 
89
error_nolock:
90
        return err;
91
error:
92
        spin_unlock_bh(&x->lock);
93
        goto error_nolock;
94
}
95
EXPORT_SYMBOL_GPL(xfrm_output);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.