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

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/klassert/ipsec-next

Steffen Klassert says:

====================
pull request (net-next): ipsec-next 2020-03-28

1) Use kmem_cache_zalloc() instead of kmem_cache_alloc()
in xfrm_state_alloc(). From Huang Zijiang.

2) esp_output_fill_trailer() is the same in IPv4 and IPv6,
so share this function to avoide code duplcation.
From Raed Salem.

3) Add offload support for esp beet mode.
From Xin Long.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+112 -34
+16
include/net/esp.h
··· 11 11 return (struct ip_esp_hdr *)skb_transport_header(skb); 12 12 } 13 13 14 + static inline void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) 15 + { 16 + /* Fill padding... */ 17 + if (tfclen) { 18 + memset(tail, 0, tfclen); 19 + tail += tfclen; 20 + } 21 + do { 22 + int i; 23 + for (i = 0; i < plen - 2; i++) 24 + tail[i] = i + 1; 25 + } while (0); 26 + tail[plen - 2] = plen - 2; 27 + tail[plen - 1] = proto; 28 + } 29 + 14 30 struct esp_info { 15 31 struct ip_esp_hdr *esph; 16 32 __be64 seqno;
-16
net/ipv4/esp4.c
··· 341 341 esp_output_done(base, err); 342 342 } 343 343 344 - static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) 345 - { 346 - /* Fill padding... */ 347 - if (tfclen) { 348 - memset(tail, 0, tfclen); 349 - tail += tfclen; 350 - } 351 - do { 352 - int i; 353 - for (i = 0; i < plen - 2; i++) 354 - tail[i] = i + 1; 355 - } while (0); 356 - tail[plen - 2] = plen - 2; 357 - tail[plen - 1] = proto; 358 - } 359 - 360 344 static struct ip_esp_hdr *esp_output_udp_encap(struct sk_buff *skb, 361 345 int encap_type, 362 346 struct esp_info *esp,
+32
net/ipv4/esp4_offload.c
··· 132 132 return segs; 133 133 } 134 134 135 + static struct sk_buff *xfrm4_beet_gso_segment(struct xfrm_state *x, 136 + struct sk_buff *skb, 137 + netdev_features_t features) 138 + { 139 + struct xfrm_offload *xo = xfrm_offload(skb); 140 + struct sk_buff *segs = ERR_PTR(-EINVAL); 141 + const struct net_offload *ops; 142 + int proto = xo->proto; 143 + 144 + skb->transport_header += x->props.header_len; 145 + 146 + if (proto == IPPROTO_BEETPH) { 147 + struct ip_beet_phdr *ph = (struct ip_beet_phdr *)skb->data; 148 + 149 + skb->transport_header += ph->hdrlen * 8; 150 + proto = ph->nexthdr; 151 + } else if (x->sel.family != AF_INET6) { 152 + skb->transport_header -= IPV4_BEET_PHMAXLEN; 153 + } else if (proto == IPPROTO_TCP) { 154 + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV4; 155 + } 156 + 157 + __skb_pull(skb, skb_transport_offset(skb)); 158 + ops = rcu_dereference(inet_offloads[proto]); 159 + if (likely(ops && ops->callbacks.gso_segment)) 160 + segs = ops->callbacks.gso_segment(skb, features); 161 + 162 + return segs; 163 + } 164 + 135 165 static struct sk_buff *xfrm4_outer_mode_gso_segment(struct xfrm_state *x, 136 166 struct sk_buff *skb, 137 167 netdev_features_t features) ··· 171 141 return xfrm4_tunnel_gso_segment(x, skb, features); 172 142 case XFRM_MODE_TRANSPORT: 173 143 return xfrm4_transport_gso_segment(x, skb, features); 144 + case XFRM_MODE_BEET: 145 + return xfrm4_beet_gso_segment(x, skb, features); 174 146 } 175 147 176 148 return ERR_PTR(-EOPNOTSUPP);
-16
net/ipv6/esp6.c
··· 207 207 esp_output_done(base, err); 208 208 } 209 209 210 - static void esp_output_fill_trailer(u8 *tail, int tfclen, int plen, __u8 proto) 211 - { 212 - /* Fill padding... */ 213 - if (tfclen) { 214 - memset(tail, 0, tfclen); 215 - tail += tfclen; 216 - } 217 - do { 218 - int i; 219 - for (i = 0; i < plen - 2; i++) 220 - tail[i] = i + 1; 221 - } while (0); 222 - tail[plen - 2] = plen - 2; 223 - tail[plen - 1] = proto; 224 - } 225 - 226 210 int esp6_output_head(struct xfrm_state *x, struct sk_buff *skb, struct esp_info *esp) 227 211 { 228 212 u8 *tail;
+36
net/ipv6/esp6_offload.c
··· 159 159 return segs; 160 160 } 161 161 162 + static struct sk_buff *xfrm6_beet_gso_segment(struct xfrm_state *x, 163 + struct sk_buff *skb, 164 + netdev_features_t features) 165 + { 166 + struct xfrm_offload *xo = xfrm_offload(skb); 167 + struct sk_buff *segs = ERR_PTR(-EINVAL); 168 + const struct net_offload *ops; 169 + int proto = xo->proto; 170 + 171 + skb->transport_header += x->props.header_len; 172 + 173 + if (proto == IPPROTO_BEETPH) { 174 + struct ip_beet_phdr *ph = (struct ip_beet_phdr *)skb->data; 175 + 176 + skb->transport_header += ph->hdrlen * 8; 177 + proto = ph->nexthdr; 178 + } 179 + 180 + if (x->sel.family != AF_INET6) { 181 + skb->transport_header -= 182 + (sizeof(struct ipv6hdr) - sizeof(struct iphdr)); 183 + 184 + if (proto == IPPROTO_TCP) 185 + skb_shinfo(skb)->gso_type |= SKB_GSO_TCPV6; 186 + } 187 + 188 + __skb_pull(skb, skb_transport_offset(skb)); 189 + ops = rcu_dereference(inet6_offloads[proto]); 190 + if (likely(ops && ops->callbacks.gso_segment)) 191 + segs = ops->callbacks.gso_segment(skb, features); 192 + 193 + return segs; 194 + } 195 + 162 196 static struct sk_buff *xfrm6_outer_mode_gso_segment(struct xfrm_state *x, 163 197 struct sk_buff *skb, 164 198 netdev_features_t features) ··· 202 168 return xfrm6_tunnel_gso_segment(x, skb, features); 203 169 case XFRM_MODE_TRANSPORT: 204 170 return xfrm6_transport_gso_segment(x, skb, features); 171 + case XFRM_MODE_BEET: 172 + return xfrm6_beet_gso_segment(x, skb, features); 205 173 } 206 174 207 175 return ERR_PTR(-EOPNOTSUPP);
+27 -1
net/xfrm/xfrm_device.c
··· 46 46 pskb_pull(skb, skb->mac_len + x->props.header_len); 47 47 } 48 48 49 + static void __xfrm_mode_beet_prep(struct xfrm_state *x, struct sk_buff *skb, 50 + unsigned int hsize) 51 + { 52 + struct xfrm_offload *xo = xfrm_offload(skb); 53 + int phlen = 0; 54 + 55 + if (xo->flags & XFRM_GSO_SEGMENT) 56 + skb->transport_header = skb->network_header + hsize; 57 + 58 + skb_reset_mac_len(skb); 59 + if (x->sel.family != AF_INET6) { 60 + phlen = IPV4_BEET_PHMAXLEN; 61 + if (x->outer_mode.family == AF_INET6) 62 + phlen += sizeof(struct ipv6hdr) - sizeof(struct iphdr); 63 + } 64 + 65 + pskb_pull(skb, skb->mac_len + hsize + (x->props.header_len - phlen)); 66 + } 67 + 49 68 /* Adjust pointers into the packet when IPsec is done at layer2 */ 50 69 static void xfrm_outer_mode_prep(struct xfrm_state *x, struct sk_buff *skb) 51 70 { ··· 85 66 return __xfrm_transport_prep(x, skb, 86 67 sizeof(struct ipv6hdr)); 87 68 break; 69 + case XFRM_MODE_BEET: 70 + if (x->outer_mode.family == AF_INET) 71 + return __xfrm_mode_beet_prep(x, skb, 72 + sizeof(struct iphdr)); 73 + if (x->outer_mode.family == AF_INET6) 74 + return __xfrm_mode_beet_prep(x, skb, 75 + sizeof(struct ipv6hdr)); 76 + break; 88 77 case XFRM_MODE_ROUTEOPTIMIZATION: 89 78 case XFRM_MODE_IN_TRIGGER: 90 - case XFRM_MODE_BEET: 91 79 break; 92 80 } 93 81 }
+1 -1
net/xfrm/xfrm_state.c
··· 612 612 { 613 613 struct xfrm_state *x; 614 614 615 - x = kmem_cache_alloc(xfrm_state_cache, GFP_ATOMIC | __GFP_ZERO); 615 + x = kmem_cache_zalloc(xfrm_state_cache, GFP_ATOMIC); 616 616 617 617 if (x) { 618 618 write_pnet(&x->xs_net, net);