From 611f1929a888cf3e7fa0298386621a16648d8c4f Mon Sep 17 00:00:00 2001 From: Herbert Xu Date: Thu, 7 Aug 2003 07:17:29 -0700 Subject: [PATCH] [IPSEC]: Use xfrm_rcv for xfrm tunnel packets. --- net/ipv4/ipcomp.c | 1 + net/ipv4/xfrm4_input.c | 16 ++++++++++- net/ipv4/xfrm4_tunnel.c | 63 ++--------------------------------------- 3 files changed, 19 insertions(+), 61 deletions(-) diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c index 5ebb565c77d99..a713530ae557b 100644 --- a/net/ipv4/ipcomp.c +++ b/net/ipv4/ipcomp.c @@ -279,6 +279,7 @@ static struct xfrm_state *ipcomp_tunnel_create(struct xfrm_state *x) t->props.family = AF_INET; t->props.mode = 1; t->props.saddr.a4 = x->props.saddr.a4; + t->props.flags = x->props.flags; t->type = xfrm_get_type(IPPROTO_IPIP, t->props.family); if (t->type == NULL) diff --git a/net/ipv4/xfrm4_input.c b/net/ipv4/xfrm4_input.c index 2412f93986828..9040408dbf81d 100644 --- a/net/ipv4/xfrm4_input.c +++ b/net/ipv4/xfrm4_input.c @@ -27,6 +27,20 @@ static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff IP_ECN_set_ce(inner_iph); } +static int xfrm4_parse_spi(struct sk_buff *skb, u8 nexthdr, u32 *spi, u32 *seq) +{ + switch (nexthdr) { + case IPPROTO_IPIP: + if (!pskb_may_pull(skb, sizeof(struct iphdr))) + return -EINVAL; + *spi = skb->nh.iph->saddr; + *seq = 0; + return 0; + } + + return xfrm_parse_spi(skb, nexthdr, spi, seq); +} + int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) { int err; @@ -36,7 +50,7 @@ int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type) int xfrm_nr = 0; int decaps = 0; - if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) + if ((err = xfrm4_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) != 0) goto drop; do { diff --git a/net/ipv4/xfrm4_tunnel.c b/net/ipv4/xfrm4_tunnel.c index 1d0d2417893b0..c4389b6f8d291 100644 --- a/net/ipv4/xfrm4_tunnel.c +++ b/net/ipv4/xfrm4_tunnel.c @@ -83,31 +83,8 @@ error_nolock: return err; } -static inline void ipip_ecn_decapsulate(struct iphdr *outer_iph, struct sk_buff *skb) -{ - struct iphdr *inner_iph = skb->nh.iph; - - if (INET_ECN_is_ce(outer_iph->tos) && - INET_ECN_is_not_ce(inner_iph->tos)) - IP_ECN_set_ce(inner_iph); -} - static int ipip_xfrm_rcv(struct xfrm_state *x, struct xfrm_decap_state *decap, struct sk_buff *skb) { - struct iphdr *outer_iph = skb->nh.iph; - - if (!pskb_may_pull(skb, sizeof(struct iphdr))) - return -EINVAL; - skb->mac.raw = skb->nh.raw; - skb->nh.raw = skb->data; - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); - dst_release(skb->dst); - skb->dst = NULL; - skb->protocol = htons(ETH_P_IP); - skb->pkt_type = PACKET_HOST; - ipip_ecn_decapsulate(outer_iph, skb); - netif_rx(skb); - return 0; } @@ -149,46 +126,12 @@ int xfrm4_tunnel_deregister(struct xfrm_tunnel *handler) static int ipip_rcv(struct sk_buff *skb) { struct xfrm_tunnel *handler = ipip_handler; - struct xfrm_state *x = NULL; - int err; /* Tunnel devices take precedence. */ - if (handler) { - err = handler->handler(skb); - if (!err) - goto out; - } + if (handler && handler->handler(skb) == 0) + return 0; - x = xfrm_state_lookup((xfrm_address_t *)&skb->nh.iph->daddr, - skb->nh.iph->saddr, - IPPROTO_IPIP, AF_INET); - - if (!x) - goto drop; - - spin_lock(&x->lock); - - if (unlikely(x->km.state != XFRM_STATE_VALID)) - goto drop_unlock; - - err = ipip_xfrm_rcv(x, NULL, skb); - if (err) - goto drop_unlock; - - x->curlft.bytes += skb->len; - x->curlft.packets++; - spin_unlock(&x->lock); - xfrm_state_put(x); -out: - return err; - -drop_unlock: - spin_unlock(&x->lock); - xfrm_state_put(x); -drop: - err = NET_RX_DROP; - kfree_skb(skb); - goto out; + return xfrm4_rcv_encap(skb, 0); } static void ipip_err(struct sk_buff *skb, u32 info) -- 2.53.0