Steffen Klassert says: ==================== pull request (net-next): ipsec-next 2022-05-13 1) Cleanups for the code behind the XFRM offload API. This is a preparation for the extension of the API for policy offload. From Leon Romanovsky. * 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next: xfrm: drop not needed flags variable in XFRM offload struct net/mlx5e: Use XFRM state direction instead of flags netdevsim: rely on XFRM state direction instead of flags ixgbe: propagate XFRM offload state direction instead of flags xfrm: store and rely on direction to construct offload flags xfrm: rename xfrm_state_offload struct to allow reuse xfrm: delete not used number of external headers xfrm: free not used XFRM_ESP_NO_TRAILER flag ====================
Unified · Split
| @@ -585,7 +585,7 @@ static int ixgbe_ipsec_add_sa(struct xfrm_state *xs) · 584 unmodified lines | |||
| 585 | return -EINVAL; | 585 | return -EINVAL; |
| 586 | } | 586 | } |
| 587 | 587 | ||
| 588 | if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { | 588 | if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 589 | struct rx_sa rsa; | 589 | struct rx_sa rsa; |
| 590 | 590 | ||
| 591 | if (xs->calg) { | 591 | if (xs->calg) { |
| @@ -757,7 +757,7 @@ static void ixgbe_ipsec_del_sa(struct xfrm_state *xs) · 165 unmodified lines | |||
| 757 | u32 zerobuf[4] = {0, 0, 0, 0}; | 757 | u32 zerobuf[4] = {0, 0, 0, 0}; |
| 758 | u16 sa_idx; | 758 | u16 sa_idx; |
| 759 | 759 | ||
| 760 | if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { | 760 | if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 761 | struct rx_sa *rsa; | 761 | struct rx_sa *rsa; |
| 762 | u8 ipi; | 762 | u8 ipi; |
| 763 | 763 | ||
| @@ -903,8 +903,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) · 139 unmodified lines | |||
| 903 | /* Tx IPsec offload doesn't seem to work on this | 903 | /* Tx IPsec offload doesn't seem to work on this |
| 904 | * device, so block these requests for now. | 904 | * device, so block these requests for now. |
| 905 | */ | 905 | */ |
| 906 | sam->flags = sam->flags & ~XFRM_OFFLOAD_IPV6; | 906 | if (sam->dir != XFRM_DEV_OFFLOAD_IN) { |
| 907 | if (sam->flags != XFRM_OFFLOAD_INBOUND) { | ||
| 908 | err = -EOPNOTSUPP; | 907 | err = -EOPNOTSUPP; |
| 909 | goto err_out; | 908 | goto err_out; |
| 910 | } | 909 | } |
| @@ -915,7 +914,7 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf) · 4 unmodified lines | |||
| 915 | goto err_out; | 914 | goto err_out; |
| 916 | } | 915 | } |
| 917 | 916 | ||
| 918 | xs->xso.flags = sam->flags; | 917 | xs->xso.dir = sam->dir; |
| 919 | xs->id.spi = sam->spi; | 918 | xs->id.spi = sam->spi; |
| 920 | xs->id.proto = sam->proto; | 919 | xs->id.proto = sam->proto; |
| 921 | xs->props.family = sam->family; | 920 | xs->props.family = sam->family; |
| @@ -74,7 +74,7 @@ struct ixgbe_ipsec { · 73 unmodified lines | |||
| 74 | 74 | ||
| 75 | struct sa_mbx_msg { | 75 | struct sa_mbx_msg { |
| 76 | __be32 spi; | 76 | __be32 spi; |
| 77 | u8 flags; | 77 | u8 dir; |
| 78 | u8 proto; | 78 | u8 proto; |
| 79 | u16 family; | 79 | u16 family; |
| 80 | __be32 addr[4]; | 80 | __be32 addr[4]; |
| @@ -25,7 +25,7 @@ static int ixgbevf_ipsec_set_pf_sa(struct ixgbevf_adapter *adapter, · 24 unmodified lines | |||
| 25 | 25 | ||
| 26 | /* send the important bits to the PF */ | 26 | /* send the important bits to the PF */ |
| 27 | sam = (struct sa_mbx_msg *)(&msgbuf[1]); | 27 | sam = (struct sa_mbx_msg *)(&msgbuf[1]); |
| 28 | sam->flags = xs->xso.flags; | 28 | sam->dir = xs->xso.dir; |
| 29 | sam->spi = xs->id.spi; | 29 | sam->spi = xs->id.spi; |
| 30 | sam->proto = xs->id.proto; | 30 | sam->proto = xs->id.proto; |
| 31 | sam->family = xs->props.family; | 31 | sam->family = xs->props.family; |
| @@ -280,7 +280,7 @@ static int ixgbevf_ipsec_add_sa(struct xfrm_state *xs) · 248 unmodified lines | |||
| 280 | return -EINVAL; | 280 | return -EINVAL; |
| 281 | } | 281 | } |
| 282 | 282 | ||
| 283 | if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { | 283 | if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 284 | struct rx_sa rsa; | 284 | struct rx_sa rsa; |
| 285 | 285 | ||
| 286 | if (xs->calg) { | 286 | if (xs->calg) { |
| @@ -394,7 +394,7 @@ static void ixgbevf_ipsec_del_sa(struct xfrm_state *xs) · 107 unmodified lines | |||
| 394 | adapter = netdev_priv(dev); | 394 | adapter = netdev_priv(dev); |
| 395 | ipsec = adapter->ipsec; | 395 | ipsec = adapter->ipsec; |
| 396 | 396 | ||
| 397 | if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { | 397 | if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 398 | sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX; | 398 | sa_idx = xs->xso.offload_handle - IXGBE_IPSEC_BASE_RX_INDEX; |
| 399 | 399 | ||
| 400 | if (!ipsec->rx_tbl[sa_idx].used) { | 400 | if (!ipsec->rx_tbl[sa_idx].used) { |
| @@ -57,7 +57,7 @@ struct ixgbevf_ipsec { · 56 unmodified lines | |||
| 57 | 57 | ||
| 58 | struct sa_mbx_msg { | 58 | struct sa_mbx_msg { |
| 59 | __be32 spi; | 59 | __be32 spi; |
| 60 | u8 flags; | 60 | u8 dir; |
| 61 | u8 proto; | 61 | u8 proto; |
| 62 | u16 family; | 62 | u16 family; |
| 63 | __be32 addr[4]; | 63 | __be32 addr[4]; |
| @@ -172,9 +172,9 @@ mlx5e_ipsec_build_accel_xfrm_attrs(struct mlx5e_ipsec_sa_entry *sa_entry, · 171 unmodified lines | |||
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | /* action */ | 174 | /* action */ |
| 175 | attrs->action = (!(x->xso.flags & XFRM_OFFLOAD_INBOUND)) ? | 175 | attrs->action = (x->xso.dir == XFRM_DEV_OFFLOAD_OUT) ? |
| 176 | MLX5_ACCEL_ESP_ACTION_ENCRYPT : | 176 | MLX5_ACCEL_ESP_ACTION_ENCRYPT : |
| 177 | MLX5_ACCEL_ESP_ACTION_DECRYPT; | 177 | MLX5_ACCEL_ESP_ACTION_DECRYPT; |
| 178 | /* flags */ | 178 | /* flags */ |
| 179 | attrs->flags |= (x->props.mode == XFRM_MODE_TRANSPORT) ? | 179 | attrs->flags |= (x->props.mode == XFRM_MODE_TRANSPORT) ? |
| 180 | MLX5_ACCEL_ESP_FLAGS_TRANSPORT : | 180 | MLX5_ACCEL_ESP_FLAGS_TRANSPORT : |
| @@ -306,7 +306,7 @@ static int mlx5e_xfrm_add_state(struct xfrm_state *x) · 125 unmodified lines | |||
| 306 | if (err) | 306 | if (err) |
| 307 | goto err_hw_ctx; | 307 | goto err_hw_ctx; |
| 308 | 308 | ||
| 309 | if (x->xso.flags & XFRM_OFFLOAD_INBOUND) { | 309 | if (x->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 310 | err = mlx5e_ipsec_sadb_rx_add(sa_entry); | 310 | err = mlx5e_ipsec_sadb_rx_add(sa_entry); |
| 311 | if (err) | 311 | if (err) |
| 312 | goto err_add_rule; | 312 | goto err_add_rule; |
| @@ -333,7 +333,7 @@ static void mlx5e_xfrm_del_state(struct xfrm_state *x) · 20 unmodified lines | |||
| 333 | { | 333 | { |
| 334 | struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); | 334 | struct mlx5e_ipsec_sa_entry *sa_entry = to_ipsec_sa_entry(x); |
| 335 | 335 | ||
| 336 | if (x->xso.flags & XFRM_OFFLOAD_INBOUND) | 336 | if (x->xso.dir == XFRM_DEV_OFFLOAD_IN) |
| 337 | mlx5e_ipsec_sadb_rx_del(sa_entry); | 337 | mlx5e_ipsec_sadb_rx_del(sa_entry); |
| 338 | } | 338 | } |
| 339 | 339 | ||
| @@ -171,7 +171,7 @@ static int nsim_ipsec_add_sa(struct xfrm_state *xs) · 170 unmodified lines | |||
| 171 | return ret; | 171 | return ret; |
| 172 | } | 172 | } |
| 173 | 173 | ||
| 174 | if (xs->xso.flags & XFRM_OFFLOAD_INBOUND) { | 174 | if (xs->xso.dir == XFRM_DEV_OFFLOAD_IN) { |
| 175 | sa.rx = true; | 175 | sa.rx = true; |
| 176 | 176 | ||
| 177 | if (xs->props.family == AF_INET6) | 177 | if (xs->props.family == AF_INET6) |
| @@ -126,13 +126,17 @@ struct xfrm_state_walk { · 125 unmodified lines | |||
| 126 | struct xfrm_address_filter *filter; | 126 | struct xfrm_address_filter *filter; |
| 127 | }; | 127 | }; |
| 128 | 128 | ||
| 129 | struct xfrm_state_offload { | 129 | enum { |
| 130 | XFRM_DEV_OFFLOAD_IN = 1, | ||
| 131 | XFRM_DEV_OFFLOAD_OUT, | ||
| 132 | }; | ||
| 133 | |||
| 134 | struct xfrm_dev_offload { | ||
| 130 | struct net_device *dev; | 135 | struct net_device *dev; |
| 131 | netdevice_tracker dev_tracker; | 136 | netdevice_tracker dev_tracker; |
| 132 | struct net_device *real_dev; | 137 | struct net_device *real_dev; |
| 133 | unsigned long offload_handle; | 138 | unsigned long offload_handle; |
| 134 | unsigned int num_exthdrs; | 139 | u8 dir : 2; |
| 135 | u8 flags; | ||
| 136 | }; | 140 | }; |
| 137 | 141 | ||
| 138 | struct xfrm_mode { | 142 | struct xfrm_mode { |
| @@ -247,7 +251,7 @@ struct xfrm_state { · 108 unmodified lines | |||
| 247 | struct xfrm_lifetime_cur curlft; | 251 | struct xfrm_lifetime_cur curlft; |
| 248 | struct hrtimer mtimer; | 252 | struct hrtimer mtimer; |
| 249 | 253 | ||
| 250 | struct xfrm_state_offload xso; | 254 | struct xfrm_dev_offload xso; |
| 251 | 255 | ||
| 252 | /* used to fix curlft->add_time when changing date */ | 256 | /* used to fix curlft->add_time when changing date */ |
| 253 | long saved_tmo; | 257 | long saved_tmo; |
| @@ -1006,7 +1010,7 @@ struct xfrm_offload { · 752 unmodified lines | |||
| 1006 | #define CRYPTO_FALLBACK 8 | 1010 | #define CRYPTO_FALLBACK 8 |
| 1007 | #define XFRM_GSO_SEGMENT 16 | 1011 | #define XFRM_GSO_SEGMENT 16 |
| 1008 | #define XFRM_GRO 32 | 1012 | #define XFRM_GRO 32 |
| 1009 | #define XFRM_ESP_NO_TRAILER 64 | 1013 | /* 64 is free */ |
| 1010 | #define XFRM_DEV_RESUME 128 | 1014 | #define XFRM_DEV_RESUME 128 |
| 1011 | #define XFRM_XMIT 256 | 1015 | #define XFRM_XMIT 256 |
| 1012 | 1016 | ||
| @@ -1866,7 +1870,7 @@ bool xfrm_dev_offload_ok(struct sk_buff *skb, struct xfrm_state *x); · 853 unmodified lines | |||
| 1866 | 1870 | ||
| 1867 | static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) | 1871 | static inline void xfrm_dev_state_advance_esn(struct xfrm_state *x) |
| 1868 | { | 1872 | { |
| 1869 | struct xfrm_state_offload *xso = &x->xso; | 1873 | struct xfrm_dev_offload *xso = &x->xso; |
| 1870 | 1874 | ||
| 1871 | if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn) | 1875 | if (xso->dev && xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn) |
| 1872 | xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); | 1876 | xso->dev->xfrmdev_ops->xdo_dev_state_advance_esn(x); |
| @@ -1892,7 +1896,7 @@ static inline bool xfrm_dst_offload_ok(struct dst_entry *dst) · 19 unmodified lines | |||
| 1892 | 1896 | ||
| 1893 | static inline void xfrm_dev_state_delete(struct xfrm_state *x) | 1897 | static inline void xfrm_dev_state_delete(struct xfrm_state *x) |
| 1894 | { | 1898 | { |
| 1895 | struct xfrm_state_offload *xso = &x->xso; | 1899 | struct xfrm_dev_offload *xso = &x->xso; |
| 1896 | 1900 | ||
| 1897 | if (xso->dev) | 1901 | if (xso->dev) |
| 1898 | xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); | 1902 | xso->dev->xfrmdev_ops->xdo_dev_state_delete(x); |
| @@ -1900,7 +1904,7 @@ static inline void xfrm_dev_state_delete(struct xfrm_state *x) · 1 unmodified line | |||
| 1900 | 1904 | ||
| 1901 | static inline void xfrm_dev_state_free(struct xfrm_state *x) | 1905 | static inline void xfrm_dev_state_free(struct xfrm_state *x) |
| 1902 | { | 1906 | { |
| 1903 | struct xfrm_state_offload *xso = &x->xso; | 1907 | struct xfrm_dev_offload *xso = &x->xso; |
| 1904 | struct net_device *dev = xso->dev; | 1908 | struct net_device *dev = xso->dev; |
| 1905 | 1909 | ||
| 1906 | if (dev && dev->xfrmdev_ops) { | 1910 | if (dev && dev->xfrmdev_ops) { |
| @@ -705,7 +705,6 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb) · 704 unmodified lines | |||
| 705 | static inline int esp_remove_trailer(struct sk_buff *skb) | 705 | static inline int esp_remove_trailer(struct sk_buff *skb) |
| 706 | { | 706 | { |
| 707 | struct xfrm_state *x = xfrm_input_state(skb); | 707 | struct xfrm_state *x = xfrm_input_state(skb); |
| 708 | struct xfrm_offload *xo = xfrm_offload(skb); | ||
| 709 | struct crypto_aead *aead = x->data; | 708 | struct crypto_aead *aead = x->data; |
| 710 | int alen, hlen, elen; | 709 | int alen, hlen, elen; |
| 711 | int padlen, trimlen; | 710 | int padlen, trimlen; |
| @@ -717,11 +716,6 @@ static inline int esp_remove_trailer(struct sk_buff *skb) · 5 unmodified lines | |||
| 717 | hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); | 716 | hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); |
| 718 | elen = skb->len - hlen; | 717 | elen = skb->len - hlen; |
| 719 | 718 | ||
| 720 | if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { | ||
| 721 | ret = xo->proto; | ||
| 722 | goto out; | ||
| 723 | } | ||
| 724 | |||
| 725 | if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) | 719 | if (skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2)) |
| 726 | BUG(); | 720 | BUG(); |
| 727 | 721 | ||
| @@ -741,7 +741,6 @@ static int esp6_output(struct xfrm_state *x, struct sk_buff *skb) · 740 unmodified lines | |||
| 741 | static inline int esp_remove_trailer(struct sk_buff *skb) | 741 | static inline int esp_remove_trailer(struct sk_buff *skb) |
| 742 | { | 742 | { |
| 743 | struct xfrm_state *x = xfrm_input_state(skb); | 743 | struct xfrm_state *x = xfrm_input_state(skb); |
| 744 | struct xfrm_offload *xo = xfrm_offload(skb); | ||
| 745 | struct crypto_aead *aead = x->data; | 744 | struct crypto_aead *aead = x->data; |
| 746 | int alen, hlen, elen; | 745 | int alen, hlen, elen; |
| 747 | int padlen, trimlen; | 746 | int padlen, trimlen; |
| @@ -753,11 +752,6 @@ static inline int esp_remove_trailer(struct sk_buff *skb) · 5 unmodified lines | |||
| 753 | hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); | 752 | hlen = sizeof(struct ip_esp_hdr) + crypto_aead_ivsize(aead); |
| 754 | elen = skb->len - hlen; | 753 | elen = skb->len - hlen; |
| 755 | 754 | ||
| 756 | if (xo && (xo->flags & XFRM_ESP_NO_TRAILER)) { | ||
| 757 | ret = xo->proto; | ||
| 758 | goto out; | ||
| 759 | } | ||
| 760 | |||
| 761 | ret = skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2); | 755 | ret = skb_copy_bits(skb, skb->len - alen - 2, nexthdr, 2); |
| 762 | BUG_ON(ret); | 756 | BUG_ON(ret); |
| 763 | 757 | ||
| @@ -117,7 +117,7 @@ struct sk_buff *validate_xmit_xfrm(struct sk_buff *skb, netdev_features_t featur · 116 unmodified lines | |||
| 117 | 117 | ||
| 118 | sp = skb_sec_path(skb); | 118 | sp = skb_sec_path(skb); |
| 119 | x = sp->xvec[sp->len - 1]; | 119 | x = sp->xvec[sp->len - 1]; |
| 120 | if (xo->flags & XFRM_GRO || x->xso.flags & XFRM_OFFLOAD_INBOUND) | 120 | if (xo->flags & XFRM_GRO || x->xso.dir == XFRM_DEV_OFFLOAD_IN) |
| 121 | return skb; | 121 | return skb; |
| 122 | 122 | ||
| 123 | /* This skb was already validated on the upper/virtual dev */ | 123 | /* This skb was already validated on the upper/virtual dev */ |
| @@ -212,7 +212,7 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, · 88 unmodified lines | |||
| 212 | int err; | 212 | int err; |
| 213 | struct dst_entry *dst; | 213 | struct dst_entry *dst; |
| 214 | struct net_device *dev; | 214 | struct net_device *dev; |
| 215 | struct xfrm_state_offload *xso = &x->xso; | 215 | struct xfrm_dev_offload *xso = &x->xso; |
| 216 | xfrm_address_t *saddr; | 216 | xfrm_address_t *saddr; |
| 217 | xfrm_address_t *daddr; | 217 | xfrm_address_t *daddr; |
| 218 | 218 | ||
| @@ -264,15 +264,16 @@ int xfrm_dev_state_add(struct net *net, struct xfrm_state *x, · 45 unmodified lines | |||
| 264 | xso->dev = dev; | 264 | xso->dev = dev; |
| 265 | netdev_tracker_alloc(dev, &xso->dev_tracker, GFP_ATOMIC); | 265 | netdev_tracker_alloc(dev, &xso->dev_tracker, GFP_ATOMIC); |
| 266 | xso->real_dev = dev; | 266 | xso->real_dev = dev; |
| 267 | xso->num_exthdrs = 1; | 267 | |
| 268 | /* Don't forward bit that is not implemented */ | 268 | if (xuo->flags & XFRM_OFFLOAD_INBOUND) |
| 269 | xso->flags = xuo->flags & ~XFRM_OFFLOAD_IPV6; | 269 | xso->dir = XFRM_DEV_OFFLOAD_IN; |
| 270 | else | ||
| 271 | xso->dir = XFRM_DEV_OFFLOAD_OUT; | ||
| 270 | 272 | ||
| 271 | err = dev->xfrmdev_ops->xdo_dev_state_add(x); | 273 | err = dev->xfrmdev_ops->xdo_dev_state_add(x); |
| 272 | if (err) { | 274 | if (err) { |
| 273 | xso->num_exthdrs = 0; | ||
| 274 | xso->flags = 0; | ||
| 275 | xso->dev = NULL; | 275 | xso->dev = NULL; |
| 276 | xso->dir = 0; | ||
| 276 | xso->real_dev = NULL; | 277 | xso->real_dev = NULL; |
| 277 | dev_put_track(dev, &xso->dev_tracker); | 278 | dev_put_track(dev, &xso->dev_tracker); |
| 278 | 279 | ||
| @@ -751,7 +751,7 @@ xfrm_dev_state_flush_secctx_check(struct net *net, struct net_device *dev, bool · 750 unmodified lines | |||
| 751 | 751 | ||
| 752 | for (i = 0; i <= net->xfrm.state_hmask; i++) { | 752 | for (i = 0; i <= net->xfrm.state_hmask; i++) { |
| 753 | struct xfrm_state *x; | 753 | struct xfrm_state *x; |
| 754 | struct xfrm_state_offload *xso; | 754 | struct xfrm_dev_offload *xso; |
| 755 | 755 | ||
| 756 | hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { | 756 | hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { |
| 757 | xso = &x->xso; | 757 | xso = &x->xso; |
| @@ -835,7 +835,7 @@ int xfrm_dev_state_flush(struct net *net, struct net_device *dev, bool task_vali · 77 unmodified lines | |||
| 835 | err = -ESRCH; | 835 | err = -ESRCH; |
| 836 | for (i = 0; i <= net->xfrm.state_hmask; i++) { | 836 | for (i = 0; i <= net->xfrm.state_hmask; i++) { |
| 837 | struct xfrm_state *x; | 837 | struct xfrm_state *x; |
| 838 | struct xfrm_state_offload *xso; | 838 | struct xfrm_dev_offload *xso; |
| 839 | restart: | 839 | restart: |
| 840 | hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { | 840 | hlist_for_each_entry(x, net->xfrm.state_bydst+i, bydst) { |
| 841 | xso = &x->xso; | 841 | xso = &x->xso; |
| @@ -840,7 +840,7 @@ static int copy_sec_ctx(struct xfrm_sec_ctx *s, struct sk_buff *skb) · 839 unmodified lines | |||
| 840 | return 0; | 840 | return 0; |
| 841 | } | 841 | } |
| 842 | 842 | ||
| 843 | static int copy_user_offload(struct xfrm_state_offload *xso, struct sk_buff *skb) | 843 | static int copy_user_offload(struct xfrm_dev_offload *xso, struct sk_buff *skb) |
| 844 | { | 844 | { |
| 845 | struct xfrm_user_offload *xuo; | 845 | struct xfrm_user_offload *xuo; |
| 846 | struct nlattr *attr; | 846 | struct nlattr *attr; |
| @@ -852,7 +852,8 @@ static int copy_user_offload(struct xfrm_state_offload *xso, struct sk_buff *skb · 5 unmodified lines | |||
| 852 | xuo = nla_data(attr); | 852 | xuo = nla_data(attr); |
| 853 | memset(xuo, 0, sizeof(*xuo)); | 853 | memset(xuo, 0, sizeof(*xuo)); |
| 854 | xuo->ifindex = xso->dev->ifindex; | 854 | xuo->ifindex = xso->dev->ifindex; |
| 855 | xuo->flags = xso->flags; | 855 | if (xso->dir == XFRM_DEV_OFFLOAD_IN) |
| 856 | xuo->flags = XFRM_OFFLOAD_INBOUND; | ||
| 856 | 857 | ||
| 857 | return 0; | 858 | return 0; |
| 858 | } | 859 | } |