Skip to content

Commit ab244a3

Browse files
Chiachang Wangklassert
authored andcommitted
xfrm: Migrate offload configuration
Add hardware offload configuration to XFRM_MSG_MIGRATE using an option netlink attribute XFRMA_OFFLOAD_DEV. In the existing xfrm_state_migrate(), the xfrm_init_state() is called assuming no hardware offload by default. Even the original xfrm_state is configured with offload, the setting will be reset. If the device is configured with hardware offload, it's reasonable to allow the device to maintain its hardware offload mode. But the device will end up with offload disabled after receiving a migration event when the device migrates the connection from one netdev to another one. The devices that support migration may work with different underlying networks, such as mobile devices. The hardware setting should be forwarded to the different netdev based on the migration configuration. This change provides the capability for user space to migrate from one netdev to another. Test: Tested with kernel test in the Android tree located in https://android.googlesource.com/kernel/tests/ The xfrm_tunnel_test.py under the tests folder in particular. Signed-off-by: Chiachang Wang <[email protected]> Reviewed-by: Leon Romanovsky <[email protected]> Signed-off-by: Steffen Klassert <[email protected]>
1 parent 197c297 commit ab244a3

File tree

5 files changed

+29
-9
lines changed

5 files changed

+29
-9
lines changed

include/net/xfrm.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1904,12 +1904,16 @@ struct xfrm_state *xfrm_migrate_state_find(struct xfrm_migrate *m, struct net *n
19041904
u32 if_id);
19051905
struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
19061906
struct xfrm_migrate *m,
1907-
struct xfrm_encap_tmpl *encap);
1907+
struct xfrm_encap_tmpl *encap,
1908+
struct net *net,
1909+
struct xfrm_user_offload *xuo,
1910+
struct netlink_ext_ack *extack);
19081911
int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
19091912
struct xfrm_migrate *m, int num_bundles,
19101913
struct xfrm_kmaddress *k, struct net *net,
19111914
struct xfrm_encap_tmpl *encap, u32 if_id,
1912-
struct netlink_ext_ack *extack);
1915+
struct netlink_ext_ack *extack,
1916+
struct xfrm_user_offload *xuo);
19131917
#endif
19141918

19151919
int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport);

net/key/af_key.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2630,7 +2630,7 @@ static int pfkey_migrate(struct sock *sk, struct sk_buff *skb,
26302630
}
26312631

26322632
return xfrm_migrate(&sel, dir, XFRM_POLICY_TYPE_MAIN, m, i,
2633-
kma ? &k : NULL, net, NULL, 0, NULL);
2633+
kma ? &k : NULL, net, NULL, 0, NULL, NULL);
26342634

26352635
out:
26362636
return err;

net/xfrm/xfrm_policy.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4630,7 +4630,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
46304630
struct xfrm_migrate *m, int num_migrate,
46314631
struct xfrm_kmaddress *k, struct net *net,
46324632
struct xfrm_encap_tmpl *encap, u32 if_id,
4633-
struct netlink_ext_ack *extack)
4633+
struct netlink_ext_ack *extack, struct xfrm_user_offload *xuo)
46344634
{
46354635
int i, err, nx_cur = 0, nx_new = 0;
46364636
struct xfrm_policy *pol = NULL;
@@ -4663,7 +4663,7 @@ int xfrm_migrate(const struct xfrm_selector *sel, u8 dir, u8 type,
46634663
if ((x = xfrm_migrate_state_find(mp, net, if_id))) {
46644664
x_cur[nx_cur] = x;
46654665
nx_cur++;
4666-
xc = xfrm_state_migrate(x, mp, encap);
4666+
xc = xfrm_state_migrate(x, mp, encap, net, xuo, extack);
46674667
if (xc) {
46684668
x_new[nx_new] = xc;
46694669
nx_new++;

net/xfrm/xfrm_state.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2120,7 +2120,10 @@ EXPORT_SYMBOL(xfrm_migrate_state_find);
21202120

21212121
struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
21222122
struct xfrm_migrate *m,
2123-
struct xfrm_encap_tmpl *encap)
2123+
struct xfrm_encap_tmpl *encap,
2124+
struct net *net,
2125+
struct xfrm_user_offload *xuo,
2126+
struct netlink_ext_ack *extack)
21242127
{
21252128
struct xfrm_state *xc;
21262129

@@ -2136,6 +2139,10 @@ struct xfrm_state *xfrm_state_migrate(struct xfrm_state *x,
21362139
memcpy(&xc->id.daddr, &m->new_daddr, sizeof(xc->id.daddr));
21372140
memcpy(&xc->props.saddr, &m->new_saddr, sizeof(xc->props.saddr));
21382141

2142+
/* configure the hardware if offload is requested */
2143+
if (xuo && xfrm_dev_state_add(net, xc, xuo, extack))
2144+
goto error;
2145+
21392146
/* add state */
21402147
if (xfrm_addr_equal(&x->id.daddr, &m->new_daddr, m->new_family)) {
21412148
/* a care is needed when the destination address of the

net/xfrm/xfrm_user.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,6 +3069,7 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
30693069
int n = 0;
30703070
struct net *net = sock_net(skb->sk);
30713071
struct xfrm_encap_tmpl *encap = NULL;
3072+
struct xfrm_user_offload *xuo = NULL;
30723073
u32 if_id = 0;
30733074

30743075
if (!attrs[XFRMA_MIGRATE]) {
@@ -3099,11 +3100,19 @@ static int xfrm_do_migrate(struct sk_buff *skb, struct nlmsghdr *nlh,
30993100
if (attrs[XFRMA_IF_ID])
31003101
if_id = nla_get_u32(attrs[XFRMA_IF_ID]);
31013102

3103+
if (attrs[XFRMA_OFFLOAD_DEV]) {
3104+
xuo = kmemdup(nla_data(attrs[XFRMA_OFFLOAD_DEV]),
3105+
sizeof(*xuo), GFP_KERNEL);
3106+
if (!xuo) {
3107+
err = -ENOMEM;
3108+
goto error;
3109+
}
3110+
}
31023111
err = xfrm_migrate(&pi->sel, pi->dir, type, m, n, kmp, net, encap,
3103-
if_id, extack);
3104-
3112+
if_id, extack, xuo);
3113+
error:
31053114
kfree(encap);
3106-
3115+
kfree(xuo);
31073116
return err;
31083117
}
31093118
#else

0 commit comments

Comments
 (0)