Skip to content

Commit

Permalink
vxlan: Use checksum partial with remote checksum offload
Browse files Browse the repository at this point in the history
Change remote checksum handling to set checksum partial as default
behavior. Added an iflink parameter to configure not using
checksum partial (calling csum_partial to update checksum).

Signed-off-by: Tom Herbert <therbert@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Tom Herbert authored and David S. Miller committed Feb 11, 2015
1 parent 15e2396 commit 0ace2ca
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 7 deletions.
25 changes: 19 additions & 6 deletions drivers/net/vxlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -555,7 +555,8 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
unsigned int off,
struct vxlanhdr *vh, size_t hdrlen,
u32 data, struct gro_remcsum *grc)
u32 data, struct gro_remcsum *grc,
bool nopartial)
{
size_t start, offset, plen;

Expand All @@ -580,7 +581,7 @@ static struct vxlanhdr *vxlan_gro_remcsum(struct sk_buff *skb,
}

skb_gro_remcsum_process(skb, (void *)vh + hdrlen,
start, offset, grc, true);
start, offset, grc, nopartial);

skb->remcsum_offload = 1;

Expand Down Expand Up @@ -618,7 +619,9 @@ static struct sk_buff **vxlan_gro_receive(struct sk_buff **head,

if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
vh = vxlan_gro_remcsum(skb, off_vx, vh, sizeof(struct vxlanhdr),
ntohl(vh->vx_vni), &grc);
ntohl(vh->vx_vni), &grc,
!!(vs->flags &
VXLAN_F_REMCSUM_NOPARTIAL));

if (!vh)
goto out;
Expand Down Expand Up @@ -1155,7 +1158,7 @@ static void vxlan_igmp_leave(struct work_struct *work)
}

static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh,
size_t hdrlen, u32 data)
size_t hdrlen, u32 data, bool nopartial)
{
size_t start, offset, plen;

Expand All @@ -1171,7 +1174,8 @@ static struct vxlanhdr *vxlan_remcsum(struct sk_buff *skb, struct vxlanhdr *vh,

vh = (struct vxlanhdr *)(udp_hdr(skb) + 1);

skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset, true);
skb_remcsum_process(skb, (void *)vh + hdrlen, start, offset,
nopartial);

return vh;
}
Expand Down Expand Up @@ -1208,7 +1212,8 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb)
goto drop;

if ((flags & VXLAN_HF_RCO) && (vs->flags & VXLAN_F_REMCSUM_RX)) {
vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni);
vxh = vxlan_remcsum(skb, vxh, sizeof(struct vxlanhdr), vni,
!!(vs->flags & VXLAN_F_REMCSUM_NOPARTIAL));
if (!vxh)
goto drop;

Expand Down Expand Up @@ -2437,6 +2442,7 @@ static const struct nla_policy vxlan_policy[IFLA_VXLAN_MAX + 1] = {
[IFLA_VXLAN_REMCSUM_TX] = { .type = NLA_U8 },
[IFLA_VXLAN_REMCSUM_RX] = { .type = NLA_U8 },
[IFLA_VXLAN_GBP] = { .type = NLA_FLAG, },
[IFLA_VXLAN_REMCSUM_NOPARTIAL] = { .type = NLA_FLAG },
};

static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[])
Expand Down Expand Up @@ -2760,6 +2766,9 @@ static int vxlan_newlink(struct net *src_net, struct net_device *dev,
if (data[IFLA_VXLAN_GBP])
vxlan->flags |= VXLAN_F_GBP;

if (data[IFLA_VXLAN_REMCSUM_NOPARTIAL])
vxlan->flags |= VXLAN_F_REMCSUM_NOPARTIAL;

if (vxlan_find_vni(src_net, vni, use_ipv6 ? AF_INET6 : AF_INET,
vxlan->dst_port, vxlan->flags)) {
pr_info("duplicate VNI %u\n", vni);
Expand Down Expand Up @@ -2909,6 +2918,10 @@ static int vxlan_fill_info(struct sk_buff *skb, const struct net_device *dev)
nla_put_flag(skb, IFLA_VXLAN_GBP))
goto nla_put_failure;

if (vxlan->flags & VXLAN_F_REMCSUM_NOPARTIAL &&
nla_put_flag(skb, IFLA_VXLAN_REMCSUM_NOPARTIAL))
goto nla_put_failure;

return 0;

nla_put_failure:
Expand Down
4 changes: 3 additions & 1 deletion include/net/vxlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,13 +128,15 @@ struct vxlan_sock {
#define VXLAN_F_REMCSUM_TX 0x200
#define VXLAN_F_REMCSUM_RX 0x400
#define VXLAN_F_GBP 0x800
#define VXLAN_F_REMCSUM_NOPARTIAL 0x1000

/* Flags that are used in the receive patch. These flags must match in
* order for a socket to be shareable
*/
#define VXLAN_F_RCV_FLAGS (VXLAN_F_GBP | \
VXLAN_F_UDP_ZERO_CSUM6_RX | \
VXLAN_F_REMCSUM_RX)
VXLAN_F_REMCSUM_RX | \
VXLAN_F_REMCSUM_NOPARTIAL)

struct vxlan_sock *vxlan_sock_add(struct net *net, __be16 port,
vxlan_rcv_t *rcv, void *data,
Expand Down
1 change: 1 addition & 0 deletions include/uapi/linux/if_link.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ enum {
IFLA_VXLAN_REMCSUM_TX,
IFLA_VXLAN_REMCSUM_RX,
IFLA_VXLAN_GBP,
IFLA_VXLAN_REMCSUM_NOPARTIAL,
__IFLA_VXLAN_MAX
};
#define IFLA_VXLAN_MAX (__IFLA_VXLAN_MAX - 1)
Expand Down

0 comments on commit 0ace2ca

Please sign in to comment.