Acked-by: Linus Lüssing linus.luessing@web.de
Just gave it a go on a basic dhcpv6 setup and works fine. Though some additional checks will be needed in case of extension headers like the fragmentation or hop-by-hop (for jumbo frames for example) headers or ipsec stuff. But this patch should do for most people for now, the rest can be added with a later one.
Cheers, Linus
On Sun, Oct 24, 2010 at 03:14:23AM +0200, Marek Lindner wrote:
Signed-off-by: Marek Lindner lindner_marek@yahoo.de
batman-adv/gateway_client.c | 40 +++++++++++++++++++++++++++++++--------- 1 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/batman-adv/gateway_client.c b/batman-adv/gateway_client.c index e6cd9ac..128f851 100644 --- a/batman-adv/gateway_client.c +++ b/batman-adv/gateway_client.c @@ -25,6 +25,7 @@ #include "hard-interface.h" #include "compat.h" #include <linux/ip.h> +#include <linux/ipv6.h> #include <linux/udp.h> #include <linux/if_vlan.h>
@@ -404,6 +405,7 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) { struct ethhdr *ethhdr; struct iphdr *iphdr;
- struct ipv6hdr *ipv6hdr; struct udphdr *udphdr; unsigned int header_len = 0;
@@ -425,17 +427,32 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) }
/* check for ip header */
- if (ntohs(ethhdr->h_proto) != ETH_P_IP)
return 0;
- switch (ntohs(ethhdr->h_proto)) {
- case ETH_P_IP:
if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
return 0;
iphdr = (struct iphdr *)(skb->data + header_len);
header_len += iphdr->ihl * 4;
- if (!pskb_may_pull(skb, header_len + sizeof(struct iphdr)))
return 0;
- iphdr = (struct iphdr *)(skb->data + header_len);
- header_len += iphdr->ihl * 4;
/* check for udp header */
if (iphdr->protocol != IPPROTO_UDP)
return 0;
break;
- case ETH_P_IPV6:
if (!pskb_may_pull(skb, header_len + sizeof(struct ipv6hdr)))
return 0;
ipv6hdr = (struct ipv6hdr *)(skb->data + header_len);
header_len += sizeof(struct ipv6hdr);
- /* check for udp header */
- if (iphdr->protocol != IPPROTO_UDP)
/* check for udp header */
if (ipv6hdr->nexthdr != IPPROTO_UDP)
return 0;
break;
default: return 0;
}
if (!pskb_may_pull(skb, header_len + sizeof(struct udphdr))) return 0;
@@ -443,7 +460,12 @@ int gw_is_target(struct bat_priv *bat_priv, struct sk_buff *skb) header_len += sizeof(struct udphdr);
/* check for bootp port */
- if (ntohs(udphdr->dest) != 67)
if ((ntohs(ethhdr->h_proto) == ETH_P_IP) &&
(ntohs(udphdr->dest) != 67))
return 0;
if ((ntohs(ethhdr->h_proto) == ETH_P_IPV6) &&
(ntohs(udphdr->dest) != 547))
return 0;
if (atomic_read(&bat_priv->gw_mode) == GW_MODE_SERVER)
-- 1.7.1