Skip to content

Commit b3284df

Browse files
Florian Westphalklassert
authored andcommitted
xfrm: remove input2 indirection from xfrm_mode
No external dependencies on any module, place this in the core. Increase is about 1800 byte for xfrm_input.o. The beet helpers get added to internal header, as they can be reused from xfrm_output.c in the next patch (kernel contains several copies of them in the xfrm{4,6}_mode_beet.c files). Before: text data bss dec filename 5578 176 2364 8118 net/xfrm/xfrm_input.o 1180 64 0 1244 net/ipv4/xfrm4_mode_beet.o 171 40 0 211 net/ipv4/xfrm4_mode_transport.o 1163 40 0 1203 net/ipv4/xfrm4_mode_tunnel.o 1083 52 0 1135 net/ipv6/xfrm6_mode_beet.o 172 40 0 212 net/ipv6/xfrm6_mode_ro.o 172 40 0 212 net/ipv6/xfrm6_mode_transport.o 1056 40 0 1096 net/ipv6/xfrm6_mode_tunnel.o After: text data bss dec filename 7373 200 2364 9937 net/xfrm/xfrm_input.o 587 44 0 631 net/ipv4/xfrm4_mode_beet.o 171 32 0 203 net/ipv4/xfrm4_mode_transport.o 649 32 0 681 net/ipv4/xfrm4_mode_tunnel.o 625 44 0 669 net/ipv6/xfrm6_mode_beet.o 172 32 0 204 net/ipv6/xfrm6_mode_ro.o 172 32 0 204 net/ipv6/xfrm6_mode_transport.o 599 32 0 631 net/ipv6/xfrm6_mode_tunnel.o v2: pass inner_mode to xfrm_inner_mode_encap_remove to fix AF_UNSPEC selector breakage (bisected by Benedict Wong) Signed-off-by: Florian Westphal <fw@strlen.de> Reviewed-by: Sabrina Dubroca <sd@queasysnail.net> Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
1 parent 7613b92 commit b3284df

File tree

7 files changed

+222
-173
lines changed

7 files changed

+222
-173
lines changed

include/net/xfrm.h

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -423,19 +423,6 @@ int xfrm_register_type_offload(const struct xfrm_type_offload *type, unsigned sh
423423
int xfrm_unregister_type_offload(const struct xfrm_type_offload *type, unsigned short family);
424424

425425
struct xfrm_mode {
426-
/*
427-
* Remove encapsulation header.
428-
*
429-
* The IP header will be moved over the top of the encapsulation
430-
* header.
431-
*
432-
* On entry, the transport header shall point to where the IP header
433-
* should be and the network header shall be set to where the IP
434-
* header currently is. skb->data shall point to the start of the
435-
* payload.
436-
*/
437-
int (*input2)(struct xfrm_state *x, struct sk_buff *skb);
438-
439426
/*
440427
* Add encapsulation header.
441428
*

net/ipv4/xfrm4_mode_beet.c

Lines changed: 0 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -80,54 +80,7 @@ static int xfrm4_beet_output(struct xfrm_state *x, struct sk_buff *skb)
8080
return 0;
8181
}
8282

83-
static int xfrm4_beet_input(struct xfrm_state *x, struct sk_buff *skb)
84-
{
85-
struct iphdr *iph;
86-
int optlen = 0;
87-
int err = -EINVAL;
88-
89-
if (unlikely(XFRM_MODE_SKB_CB(skb)->protocol == IPPROTO_BEETPH)) {
90-
struct ip_beet_phdr *ph;
91-
int phlen;
92-
93-
if (!pskb_may_pull(skb, sizeof(*ph)))
94-
goto out;
95-
96-
ph = (struct ip_beet_phdr *)skb->data;
97-
98-
phlen = sizeof(*ph) + ph->padlen;
99-
optlen = ph->hdrlen * 8 + (IPV4_BEET_PHMAXLEN - phlen);
100-
if (optlen < 0 || optlen & 3 || optlen > 250)
101-
goto out;
102-
103-
XFRM_MODE_SKB_CB(skb)->protocol = ph->nexthdr;
104-
105-
if (!pskb_may_pull(skb, phlen))
106-
goto out;
107-
__skb_pull(skb, phlen);
108-
}
109-
110-
skb_push(skb, sizeof(*iph));
111-
skb_reset_network_header(skb);
112-
skb_mac_header_rebuild(skb);
113-
114-
xfrm4_beet_make_header(skb);
115-
116-
iph = ip_hdr(skb);
117-
118-
iph->ihl += optlen / 4;
119-
iph->tot_len = htons(skb->len);
120-
iph->daddr = x->sel.daddr.a4;
121-
iph->saddr = x->sel.saddr.a4;
122-
iph->check = 0;
123-
iph->check = ip_fast_csum(skb_network_header(skb), iph->ihl);
124-
err = 0;
125-
out:
126-
return err;
127-
}
128-
12983
static struct xfrm_mode xfrm4_beet_mode = {
130-
.input2 = xfrm4_beet_input,
13184
.output2 = xfrm4_beet_output,
13285
.owner = THIS_MODULE,
13386
.encap = XFRM_MODE_BEET,

net/ipv4/xfrm4_mode_tunnel.c

Lines changed: 0 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,6 @@
1515
#include <net/ip.h>
1616
#include <net/xfrm.h>
1717

18-
static inline void ipip_ecn_decapsulate(struct sk_buff *skb)
19-
{
20-
struct iphdr *inner_iph = ipip_hdr(skb);
21-
22-
if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
23-
IP_ECN_set_ce(inner_iph);
24-
}
25-
2618
/* Add encapsulation header.
2719
*
2820
* The top IP header will be constructed per RFC 2401.
@@ -71,38 +63,7 @@ static int xfrm4_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
7163
return 0;
7264
}
7365

74-
static int xfrm4_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
75-
{
76-
int err = -EINVAL;
77-
78-
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPIP)
79-
goto out;
80-
81-
if (!pskb_may_pull(skb, sizeof(struct iphdr)))
82-
goto out;
83-
84-
err = skb_unclone(skb, GFP_ATOMIC);
85-
if (err)
86-
goto out;
87-
88-
if (x->props.flags & XFRM_STATE_DECAP_DSCP)
89-
ipv4_copy_dscp(XFRM_MODE_SKB_CB(skb)->tos, ipip_hdr(skb));
90-
if (!(x->props.flags & XFRM_STATE_NOECN))
91-
ipip_ecn_decapsulate(skb);
92-
93-
skb_reset_network_header(skb);
94-
skb_mac_header_rebuild(skb);
95-
if (skb->mac_len)
96-
eth_hdr(skb)->h_proto = skb->protocol;
97-
98-
err = 0;
99-
100-
out:
101-
return err;
102-
}
103-
10466
static struct xfrm_mode xfrm4_tunnel_mode = {
105-
.input2 = xfrm4_mode_tunnel_input,
10667
.output2 = xfrm4_mode_tunnel_output,
10768
.owner = THIS_MODULE,
10869
.encap = XFRM_MODE_TUNNEL,

net/ipv6/xfrm6_mode_beet.c

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,7 @@ static int xfrm6_beet_output(struct xfrm_state *x, struct sk_buff *skb)
7676
top_iph->daddr = *(struct in6_addr *)&x->id.daddr;
7777
return 0;
7878
}
79-
80-
static int xfrm6_beet_input(struct xfrm_state *x, struct sk_buff *skb)
81-
{
82-
struct ipv6hdr *ip6h;
83-
int size = sizeof(struct ipv6hdr);
84-
int err;
85-
86-
err = skb_cow_head(skb, size + skb->mac_len);
87-
if (err)
88-
goto out;
89-
90-
__skb_push(skb, size);
91-
skb_reset_network_header(skb);
92-
skb_mac_header_rebuild(skb);
93-
94-
xfrm6_beet_make_header(skb);
95-
96-
ip6h = ipv6_hdr(skb);
97-
ip6h->payload_len = htons(skb->len - size);
98-
ip6h->daddr = x->sel.daddr.in6;
99-
ip6h->saddr = x->sel.saddr.in6;
100-
err = 0;
101-
out:
102-
return err;
103-
}
104-
10579
static struct xfrm_mode xfrm6_beet_mode = {
106-
.input2 = xfrm6_beet_input,
10780
.output2 = xfrm6_beet_output,
10881
.owner = THIS_MODULE,
10982
.encap = XFRM_MODE_BEET,

net/ipv6/xfrm6_mode_tunnel.c

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,6 @@
1818
#include <net/ipv6.h>
1919
#include <net/xfrm.h>
2020

21-
static inline void ipip6_ecn_decapsulate(struct sk_buff *skb)
22-
{
23-
struct ipv6hdr *inner_iph = ipipv6_hdr(skb);
24-
25-
if (INET_ECN_is_ce(XFRM_MODE_SKB_CB(skb)->tos))
26-
IP6_ECN_set_ce(skb, inner_iph);
27-
}
28-
2921
/* Add encapsulation header.
3022
*
3123
* The top IP header will be constructed per RFC 2401.
@@ -65,45 +57,7 @@ static int xfrm6_mode_tunnel_output(struct xfrm_state *x, struct sk_buff *skb)
6557
return 0;
6658
}
6759

68-
#define for_each_input_rcu(head, handler) \
69-
for (handler = rcu_dereference(head); \
70-
handler != NULL; \
71-
handler = rcu_dereference(handler->next))
72-
73-
74-
static int xfrm6_mode_tunnel_input(struct xfrm_state *x, struct sk_buff *skb)
75-
{
76-
int err = -EINVAL;
77-
78-
if (XFRM_MODE_SKB_CB(skb)->protocol != IPPROTO_IPV6)
79-
goto out;
80-
if (!pskb_may_pull(skb, sizeof(struct ipv6hdr)))
81-
goto out;
82-
83-
err = skb_unclone(skb, GFP_ATOMIC);
84-
if (err)
85-
goto out;
86-
87-
if (x->props.flags & XFRM_STATE_DECAP_DSCP)
88-
ipv6_copy_dscp(ipv6_get_dsfield(ipv6_hdr(skb)),
89-
ipipv6_hdr(skb));
90-
if (!(x->props.flags & XFRM_STATE_NOECN))
91-
ipip6_ecn_decapsulate(skb);
92-
93-
skb_reset_network_header(skb);
94-
skb_mac_header_rebuild(skb);
95-
if (skb->mac_len)
96-
eth_hdr(skb)->h_proto = skb->protocol;
97-
98-
err = 0;
99-
100-
out:
101-
return err;
102-
}
103-
104-
10560
static struct xfrm_mode xfrm6_tunnel_mode = {
106-
.input2 = xfrm6_mode_tunnel_input,
10761
.output2 = xfrm6_mode_tunnel_output,
10862
.owner = THIS_MODULE,
10963
.encap = XFRM_MODE_TUNNEL,

net/xfrm/xfrm_inout.h

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* SPDX-License-Identifier: GPL-2.0 */
2+
#include <linux/ipv6.h>
3+
#include <net/dsfield.h>
4+
#include <net/xfrm.h>
5+
6+
#ifndef XFRM_INOUT_H
7+
#define XFRM_INOUT_H 1
8+
9+
static inline void xfrm6_beet_make_header(struct sk_buff *skb)
10+
{
11+
struct ipv6hdr *iph = ipv6_hdr(skb);
12+
13+
iph->version = 6;
14+
15+
memcpy(iph->flow_lbl, XFRM_MODE_SKB_CB(skb)->flow_lbl,
16+
sizeof(iph->flow_lbl));
17+
iph->nexthdr = XFRM_MODE_SKB_CB(skb)->protocol;
18+
19+
ipv6_change_dsfield(iph, 0, XFRM_MODE_SKB_CB(skb)->tos);
20+
iph->hop_limit = XFRM_MODE_SKB_CB(skb)->ttl;
21+
}
22+
23+
static inline void xfrm4_beet_make_header(struct sk_buff *skb)
24+
{
25+
struct iphdr *iph = ip_hdr(skb);
26+
27+
iph->ihl = 5;
28+
iph->version = 4;
29+
30+
iph->protocol = XFRM_MODE_SKB_CB(skb)->protocol;
31+
iph->tos = XFRM_MODE_SKB_CB(skb)->tos;
32+
33+
iph->id = XFRM_MODE_SKB_CB(skb)->id;
34+
iph->frag_off = XFRM_MODE_SKB_CB(skb)->frag_off;
35+
iph->ttl = XFRM_MODE_SKB_CB(skb)->ttl;
36+
}
37+
38+
#endif

0 commit comments

Comments
 (0)