Commit f7f8ed56 authored by Antonio Quartulli's avatar Antonio Quartulli Committed by Antonio Quartulli

batman-adv: h_vlan_encapsulated_proto access refactoring

In case of a VLAN tagged frame the ethhdr pointer is
moved forward by 4 bytes so that the offset of h_proto
in struct ethhdr matches the real
h_vlan_encapsulated_proto address in the skb. While this
trickery is correct it makes the code harder to understand
and may lead to bugs in case of re-use of ethhdr for other
purposes.

This patch introduces a proto variable to make things
cleaner and easier to understand.
Signed-off-by: default avatarAntonio Quartulli <ordex@autistici.org>
Signed-off-by: default avatarMarek Lindner <lindner_marek@yahoo.de>
parent 21026059
...@@ -655,24 +655,29 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) ...@@ -655,24 +655,29 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
struct iphdr *iphdr; struct iphdr *iphdr;
struct ipv6hdr *ipv6hdr; struct ipv6hdr *ipv6hdr;
struct udphdr *udphdr; struct udphdr *udphdr;
struct vlan_ethhdr *vhdr;
__be16 proto;
/* check for ethernet header */ /* check for ethernet header */
if (!pskb_may_pull(skb, *header_len + ETH_HLEN)) if (!pskb_may_pull(skb, *header_len + ETH_HLEN))
return false; return false;
ethhdr = (struct ethhdr *)skb->data; ethhdr = (struct ethhdr *)skb->data;
proto = ethhdr->h_proto;
*header_len += ETH_HLEN; *header_len += ETH_HLEN;
/* check for initial vlan header */ /* check for initial vlan header */
if (ntohs(ethhdr->h_proto) == ETH_P_8021Q) { if (proto == htons(ETH_P_8021Q)) {
if (!pskb_may_pull(skb, *header_len + VLAN_HLEN)) if (!pskb_may_pull(skb, *header_len + VLAN_HLEN))
return false; return false;
ethhdr = (struct ethhdr *)(skb->data + VLAN_HLEN);
vhdr = (struct vlan_ethhdr *)skb->data;
proto = vhdr->h_vlan_encapsulated_proto;
*header_len += VLAN_HLEN; *header_len += VLAN_HLEN;
} }
/* check for ip header */ /* check for ip header */
switch (ntohs(ethhdr->h_proto)) { switch (proto) {
case ETH_P_IP: case htons(ETH_P_IP):
if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr))) if (!pskb_may_pull(skb, *header_len + sizeof(*iphdr)))
return false; return false;
iphdr = (struct iphdr *)(skb->data + *header_len); iphdr = (struct iphdr *)(skb->data + *header_len);
...@@ -683,7 +688,7 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) ...@@ -683,7 +688,7 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
return false; return false;
break; break;
case ETH_P_IPV6: case htons(ETH_P_IPV6):
if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr))) if (!pskb_may_pull(skb, *header_len + sizeof(*ipv6hdr)))
return false; return false;
ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len); ipv6hdr = (struct ipv6hdr *)(skb->data + *header_len);
...@@ -710,11 +715,11 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len) ...@@ -710,11 +715,11 @@ bool batadv_gw_is_dhcp_target(struct sk_buff *skb, unsigned int *header_len)
*header_len += sizeof(*udphdr); *header_len += sizeof(*udphdr);
/* check for bootp port */ /* check for bootp port */
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) && if ((proto == htons(ETH_P_IP)) &&
(ntohs(udphdr->dest) != 67)) (ntohs(udphdr->dest) != 67))
return false; return false;
if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) && if ((proto == htons(ETH_P_IPV6)) &&
(ntohs(udphdr->dest) != 547)) (ntohs(udphdr->dest) != 547))
return false; return false;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment