Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

xfrm: remove output_finish indirection from xfrm_state_afinfo

There are only two implementaions, one for ipv4 and one for ipv6.

Both are almost identical, they clear skb->cb[], set the TRANSFORMED flag
in IP(6)CB and then call the common xfrm_output() function.

By placing the IPCB handling into the common function, we avoid the need
for the output_finish indirection as the output functions can simply
use xfrm_output().

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>

authored by

Florian Westphal and committed by
Steffen Klassert
2ab6096d f3075f48

+19 -57
-1
include/net/xfrm.h
··· 361 361 const struct xfrm_type *type_dstopts; 362 362 363 363 int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb); 364 - int (*output_finish)(struct sock *sk, struct sk_buff *skb); 365 364 int (*transport_finish)(struct sk_buff *skb, 366 365 int async); 367 366 void (*local_error)(struct sk_buff *skb, u32 mtu);
+1 -22
net/ipv4/xfrm4_output.c
··· 14 14 #include <net/xfrm.h> 15 15 #include <net/icmp.h> 16 16 17 - int xfrm4_output_finish(struct sock *sk, struct sk_buff *skb) 18 - { 19 - memset(IPCB(skb), 0, sizeof(*IPCB(skb))); 20 - 21 - #ifdef CONFIG_NETFILTER 22 - IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; 23 - #endif 24 - 25 - return xfrm_output(sk, skb); 26 - } 27 - 28 17 static int __xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb) 29 18 { 30 19 struct xfrm_state *x = skb_dst(skb)->xfrm; 31 - const struct xfrm_state_afinfo *afinfo; 32 - int ret = -EAFNOSUPPORT; 33 20 34 21 #ifdef CONFIG_NETFILTER 35 22 if (!x) { ··· 25 38 } 26 39 #endif 27 40 28 - rcu_read_lock(); 29 - afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family); 30 - if (likely(afinfo)) 31 - ret = afinfo->output_finish(sk, skb); 32 - else 33 - kfree_skb(skb); 34 - rcu_read_unlock(); 35 - 36 - return ret; 41 + return xfrm_output(sk, skb); 37 42 } 38 43 39 44 int xfrm4_output(struct net *net, struct sock *sk, struct sk_buff *skb)
-1
net/ipv4/xfrm4_state.c
··· 14 14 .family = AF_INET, 15 15 .proto = IPPROTO_IPIP, 16 16 .output = xfrm4_output, 17 - .output_finish = xfrm4_output_finish, 18 17 .transport_finish = xfrm4_transport_finish, 19 18 .local_error = xfrm4_local_error, 20 19 };
+2 -32
net/ipv6/xfrm6_output.c
··· 47 47 ipv6_local_error(sk, EMSGSIZE, &fl6, mtu); 48 48 } 49 49 50 - int xfrm6_output_finish(struct sock *sk, struct sk_buff *skb) 51 - { 52 - memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); 53 - 54 - #ifdef CONFIG_NETFILTER 55 - IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 56 - #endif 57 - 58 - return xfrm_output(sk, skb); 59 - } 60 - 61 - static int __xfrm6_output_state_finish(struct xfrm_state *x, struct sock *sk, 62 - struct sk_buff *skb) 63 - { 64 - const struct xfrm_state_afinfo *afinfo; 65 - int ret = -EAFNOSUPPORT; 66 - 67 - rcu_read_lock(); 68 - afinfo = xfrm_state_afinfo_get_rcu(x->outer_mode.family); 69 - if (likely(afinfo)) 70 - ret = afinfo->output_finish(sk, skb); 71 - else 72 - kfree_skb(skb); 73 - rcu_read_unlock(); 74 - 75 - return ret; 76 - } 77 - 78 50 static int __xfrm6_output_finish(struct net *net, struct sock *sk, struct sk_buff *skb) 79 51 { 80 - struct xfrm_state *x = skb_dst(skb)->xfrm; 81 - 82 - return __xfrm6_output_state_finish(x, sk, skb); 52 + return xfrm_output(sk, skb); 83 53 } 84 54 85 55 static int __xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb) ··· 91 121 __xfrm6_output_finish); 92 122 93 123 skip_frag: 94 - return __xfrm6_output_state_finish(x, sk, skb); 124 + return xfrm_output(sk, skb); 95 125 } 96 126 97 127 int xfrm6_output(struct net *net, struct sock *sk, struct sk_buff *skb)
-1
net/ipv6/xfrm6_state.c
··· 18 18 .family = AF_INET6, 19 19 .proto = IPPROTO_IPV6, 20 20 .output = xfrm6_output, 21 - .output_finish = xfrm6_output_finish, 22 21 .transport_finish = xfrm6_transport_finish, 23 22 .local_error = xfrm6_local_error, 24 23 };
+16
net/xfrm/xfrm_output.c
··· 571 571 struct xfrm_state *x = skb_dst(skb)->xfrm; 572 572 int err; 573 573 574 + switch (x->outer_mode.family) { 575 + case AF_INET: 576 + memset(IPCB(skb), 0, sizeof(*IPCB(skb))); 577 + #ifdef CONFIG_NETFILTER 578 + IPCB(skb)->flags |= IPSKB_XFRM_TRANSFORMED; 579 + #endif 580 + break; 581 + case AF_INET6: 582 + memset(IP6CB(skb), 0, sizeof(*IP6CB(skb))); 583 + 584 + #ifdef CONFIG_NETFILTER 585 + IP6CB(skb)->flags |= IP6SKB_XFRM_TRANSFORMED; 586 + #endif 587 + break; 588 + } 589 + 574 590 secpath_reset(skb); 575 591 576 592 if (xfrm_dev_offload_ok(skb, x)) {