| @@ -555,7 +555,8 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, · 554 unmodified lines |
| 555 | static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, | 555 | static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, |
| 556 | unsigned int off, | 556 | unsigned int off, |
| 557 | struct vxlanhdr *vh, size_t hdrlen, | 557 | struct vxlanhdr *vh, size_t hdrlen, |
| 558 | u32 data, struct gro_remcsum *grc) | 558 | u32 data, struct gro_remcsum *grc, |
| | 559 | bool nopartial) |
| 559 | { | 560 | { |
| 560 | size_t start, offset, plen; | 561 | size_t start, offset, plen; |
| 561 | | 562 | |
| @@ -580,7 +581,7 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb, · 18 unmodified lines |
| 580 | } | 581 | } |
| 581 | | 582 | |
| 582 | skb_gro_remcsum_process(skb, (void *)vh + hdrlen, | 583 | skb_gro_remcsum_process(skb, (void *)vh + hdrlen, |
| 583 | start, offset, grc, true); | 584 | start, offset, grc, nopartial); |
| 584 | | 585 | |
| 585 | skb->remcsum_offload = 1; | 586 | skb->remcsum_offload = 1; |
| 586 | | 587 | |
| @@ -618,7 +619,9 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head, · 31 unmodified lines |
| 618 | | 619 | |
| 619 | if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { | 620 | if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { |
| 620 | vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr), | 621 | vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr), |
| 621 | ntohl(vh->vx_vni), &grc); | 622 | ntohl(vh->vx_vni), &grc, |
| | 623 | !!(vs->flags & |
| | 624 | VXLAN_F_REMCSUM_NOPARTIAL)); |
| 622 | | 625 | |
| 623 | if (!vh) | 626 | if (!vh) |
| 624 | goto out; | 627 | goto out; |
| @@ -1155,7 +1158,7 @@ static void vxlan_igmp_leave(struct work_struct *work) · 530 unmodified lines |
| 1155 | } | 1158 | } |
| 1156 | | 1159 | |
| 1157 | static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh, | 1160 | static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh, |
| 1158 | size_t hdrlen, u32 data) | 1161 | size_t hdrlen, u32 data, bool nopartial) |
| 1159 | { | 1162 | { |
| 1160 | size_t start, offset, plen; | 1163 | size_t start, offset, plen; |
| 1161 | | 1164 | |
| @@ -1171,7 +1174,8 @@ static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh, · 9 unmodified lines |
| 1171 | | 1174 | |
| 1172 | vh = (struct vxlanhdr *)(udp_hdr(skb) + 1); | 1175 | vh = (struct vxlanhdr *)(udp_hdr(skb) + 1); |
| 1173 | | 1176 | |
| 1174 | skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset, true); | 1177 | skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset, |
| | 1178 | nopartial); |
| 1175 | | 1179 | |
| 1176 | return vh; | 1180 | return vh; |
| 1177 | } | 1181 | } |
| @@ -1208,7 +1212,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) · 30 unmodified lines |
| 1208 | goto drop; | 1212 | goto drop; |
| 1209 | | 1213 | |
| 1210 | if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { | 1214 | if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) { |
| 1211 | vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni); | 1215 | vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni, |
| | 1216 | !!(vs->flags & VXLAN_F_REMCSUM_NOPARTIAL)); |
| 1212 | if (!vxh) | 1217 | if (!vxh) |
| 1213 | goto drop; | 1218 | goto drop; |
| 1214 | | 1219 | |
| @@ -2437,6 +2442,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = { · 1222 unmodified lines |
| 2437 | [IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 }, | 2442 | [IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 }, |
| 2438 | [IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 }, | 2443 | [IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 }, |
| 2439 | [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, }, | 2444 | [IFLA_VXLAN_GBP] = { .type = NLA_FLAG, }, |
| | 2445 | [IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG }, |
| 2440 | }; | 2446 | }; |
| 2441 | | 2447 | |
| 2442 | static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) | 2448 | static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) |
| @@ -2760,6 +2766,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev, · 317 unmodified lines |
| 2760 | if (data[IFLA_VXLAN_GBP]) | 2766 | if (data[IFLA_VXLAN_GBP]) |
| 2761 | vxlan->flags |= VXLAN_F_GBP; | 2767 | vxlan->flags |= VXLAN_F_GBP; |
| 2762 | | 2768 | |
| | 2769 | if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL]) |
| | 2770 | vxlan->flags |= VXLAN_F_REMCSUM_NOPARTIAL; |
| | 2771 | |
| 2763 | if (vxlan_find_vni(src_net, vni, use_ipv6 ? AF_INET6 : AF_INET, | 2772 | if (vxlan_find_vni(src_net, vni, use_ipv6 ? AF_INET6 : AF_INET, |
| 2764 | vxlan->dst_port, vxlan->flags)) { | 2773 | vxlan->dst_port, vxlan->flags)) { |
| 2765 | pr_info("duplicate VNI %u\n", vni); | 2774 | pr_info("duplicate VNI %u\n", vni); |
| @@ -2909,6 +2918,10 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev) · 143 unmodified lines |
| 2909 | nla_put_flag(skb, IFLA_VXLAN_GBP)) | 2918 | nla_put_flag(skb, IFLA_VXLAN_GBP)) |
| 2910 | goto nla_put_failure; | 2919 | goto nla_put_failure; |
| 2911 | | 2920 | |
| | 2921 | if (vxlan->flags & VXLAN_F_REMCSUM_NOPARTIAL && |
| | 2922 | nla_put_flag(skb, IFLA_VXLAN_REMCSUM_NOPARTIAL)) |
| | 2923 | goto nla_put_failure; |
| | 2924 | |
| 2912 | return 0; | 2925 | return 0; |
| 2913 | | 2926 | |
| 2914 | nla_put_failure: | 2927 | nla_put_failure: |