diff options
author | Pravin B Shelar <pshelar@nicira.com> | 2013-08-19 14:22:54 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-08-20 03:15:43 -0400 |
commit | 7ce04758279514ca1d8ebfe322508a4a430fe2c8 (patch) | |
tree | 80a10950fd4925fda6149dbe724360938652a86e /drivers/net/vxlan.c | |
parent | 9c2e24e16fbccf6cc1102442acc4a629f79615a7 (diff) |
vxlan: Restructure vxlan receive.
Use iptunnel_pull_header() for better code sharing.
Signed-off-by: Pravin B Shelar <pshelar@nicira.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r-- | drivers/net/vxlan.c | 22 |
1 files changed, 7 insertions, 15 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index b784ee668a4e..1afb9795105f 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -57,6 +57,7 @@ | |||
57 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) | 57 | #define VXLAN_VID_MASK (VXLAN_N_VID - 1) |
58 | /* IP header + UDP + VXLAN + Ethernet header */ | 58 | /* IP header + UDP + VXLAN + Ethernet header */ |
59 | #define VXLAN_HEADROOM (20 + 8 + 8 + 14) | 59 | #define VXLAN_HEADROOM (20 + 8 + 8 + 14) |
60 | #define VXLAN_HLEN (sizeof(struct udphdr) + sizeof(struct vxlanhdr)) | ||
60 | 61 | ||
61 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ | 62 | #define VXLAN_FLAGS 0x08000000 /* struct vxlanhdr.vx_flags required value. */ |
62 | 63 | ||
@@ -868,15 +869,12 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
868 | __u32 vni; | 869 | __u32 vni; |
869 | int err; | 870 | int err; |
870 | 871 | ||
871 | /* pop off outer UDP header */ | ||
872 | __skb_pull(skb, sizeof(struct udphdr)); | ||
873 | |||
874 | /* Need Vxlan and inner Ethernet header to be present */ | 872 | /* Need Vxlan and inner Ethernet header to be present */ |
875 | if (!pskb_may_pull(skb, sizeof(struct vxlanhdr))) | 873 | if (!pskb_may_pull(skb, VXLAN_HLEN)) |
876 | goto error; | 874 | goto error; |
877 | 875 | ||
878 | /* Drop packets with reserved bits set */ | 876 | /* Return packets with reserved bits set */ |
879 | vxh = (struct vxlanhdr *) skb->data; | 877 | vxh = (struct vxlanhdr *)(udp_hdr(skb) + 1); |
880 | if (vxh->vx_flags != htonl(VXLAN_FLAGS) || | 878 | if (vxh->vx_flags != htonl(VXLAN_FLAGS) || |
881 | (vxh->vx_vni & htonl(0xff))) { | 879 | (vxh->vx_vni & htonl(0xff))) { |
882 | netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n", | 880 | netdev_dbg(skb->dev, "invalid vxlan flags=%#x vni=%#x\n", |
@@ -884,8 +882,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
884 | goto error; | 882 | goto error; |
885 | } | 883 | } |
886 | 884 | ||
887 | __skb_pull(skb, sizeof(struct vxlanhdr)); | ||
888 | |||
889 | /* Is this VNI defined? */ | 885 | /* Is this VNI defined? */ |
890 | vni = ntohl(vxh->vx_vni) >> 8; | 886 | vni = ntohl(vxh->vx_vni) >> 8; |
891 | port = inet_sk(sk)->inet_sport; | 887 | port = inet_sk(sk)->inet_sport; |
@@ -896,7 +892,7 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
896 | goto drop; | 892 | goto drop; |
897 | } | 893 | } |
898 | 894 | ||
899 | if (!pskb_may_pull(skb, ETH_HLEN)) { | 895 | if (iptunnel_pull_header(skb, VXLAN_HLEN, htons(ETH_P_TEB))) { |
900 | vxlan->dev->stats.rx_length_errors++; | 896 | vxlan->dev->stats.rx_length_errors++; |
901 | vxlan->dev->stats.rx_errors++; | 897 | vxlan->dev->stats.rx_errors++; |
902 | goto drop; | 898 | goto drop; |
@@ -904,8 +900,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
904 | 900 | ||
905 | skb_reset_mac_header(skb); | 901 | skb_reset_mac_header(skb); |
906 | 902 | ||
907 | /* Re-examine inner Ethernet packet */ | ||
908 | oip = ip_hdr(skb); | ||
909 | skb->protocol = eth_type_trans(skb, vxlan->dev); | 903 | skb->protocol = eth_type_trans(skb, vxlan->dev); |
910 | 904 | ||
911 | /* Ignore packet loops (and multicast echo) */ | 905 | /* Ignore packet loops (and multicast echo) */ |
@@ -913,11 +907,12 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
913 | vxlan->dev->dev_addr) == 0) | 907 | vxlan->dev->dev_addr) == 0) |
914 | goto drop; | 908 | goto drop; |
915 | 909 | ||
910 | /* Re-examine inner Ethernet packet */ | ||
911 | oip = ip_hdr(skb); | ||
916 | if ((vxlan->flags & VXLAN_F_LEARN) && | 912 | if ((vxlan->flags & VXLAN_F_LEARN) && |
917 | vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source)) | 913 | vxlan_snoop(skb->dev, oip->saddr, eth_hdr(skb)->h_source)) |
918 | goto drop; | 914 | goto drop; |
919 | 915 | ||
920 | __skb_tunnel_rx(skb, vxlan->dev); | ||
921 | skb_reset_network_header(skb); | 916 | skb_reset_network_header(skb); |
922 | 917 | ||
923 | /* If the NIC driver gave us an encapsulated packet with | 918 | /* If the NIC driver gave us an encapsulated packet with |
@@ -953,9 +948,6 @@ static int vxlan_udp_encap_recv(struct sock *sk, struct sk_buff *skb) | |||
953 | 948 | ||
954 | return 0; | 949 | return 0; |
955 | error: | 950 | error: |
956 | /* Put UDP header back */ | ||
957 | __skb_push(skb, sizeof(struct udphdr)); | ||
958 | |||
959 | return 1; | 951 | return 1; |
960 | drop: | 952 | drop: |
961 | /* Consume bad packet */ | 953 | /* Consume bad packet */ |