Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 351995
b: refs/heads/master
c: 218774d
h: refs/heads/master
i:
  351993: 48d1e44
  351991: 32c8afc
v: v3
  • Loading branch information
Hannes Frederic Sowa authored and David S. Miller committed Jan 29, 2013
1 parent 7fc3302 commit bf25b36
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ee873fda3bec7c668407b837fc5519eb961fcd37
refs/heads/master: 218774dc341f219bfcf940304a081b121a0e8099
54 changes: 41 additions & 13 deletions trunk/net/ipv6/sit.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ MODULE_PARM_DESC(log_ecn_error, "Log packets received with corrupted ECN");
static int ipip6_tunnel_init(struct net_device *dev);
static void ipip6_tunnel_setup(struct net_device *dev);
static void ipip6_dev_free(struct net_device *dev);
static bool check_6rd(struct ip_tunnel *tunnel, const struct in6_addr *v6dst,
__be32 *v4dst);
static struct rtnl_link_ops sit_link_ops __read_mostly;

static int sit_net_id __read_mostly;
Expand Down Expand Up @@ -590,6 +592,15 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
return err;
}

static inline bool is_spoofed_6rd(struct ip_tunnel *tunnel, const __be32 v4addr,
const struct in6_addr *v6addr)
{
__be32 v4embed = 0;
if (check_6rd(tunnel, v6addr, &v4embed) && v4addr != v4embed)
return true;
return false;
}

static int ipip6_rcv(struct sk_buff *skb)
{
const struct iphdr *iph = ip_hdr(skb);
Expand All @@ -608,10 +619,19 @@ static int ipip6_rcv(struct sk_buff *skb)
skb->protocol = htons(ETH_P_IPV6);
skb->pkt_type = PACKET_HOST;

if ((tunnel->dev->priv_flags & IFF_ISATAP) &&
!isatap_chksrc(skb, iph, tunnel)) {
tunnel->dev->stats.rx_errors++;
goto out;
if (tunnel->dev->priv_flags & IFF_ISATAP) {
if (!isatap_chksrc(skb, iph, tunnel)) {
tunnel->dev->stats.rx_errors++;
goto out;
}
} else {
if (is_spoofed_6rd(tunnel, iph->saddr,
&ipv6_hdr(skb)->saddr) ||
is_spoofed_6rd(tunnel, iph->daddr,
&ipv6_hdr(skb)->daddr)) {
tunnel->dev->stats.rx_errors++;
goto out;
}
}

__skb_tunnel_rx(skb, tunnel->dev);
Expand Down Expand Up @@ -645,14 +665,12 @@ static int ipip6_rcv(struct sk_buff *skb)
}

/*
* Returns the embedded IPv4 address if the IPv6 address
* comes from 6rd / 6to4 (RFC 3056) addr space.
* If the IPv6 address comes from 6rd / 6to4 (RFC 3056) addr space this function
* stores the embedded IPv4 address in v4dst and returns true.
*/
static inline
__be32 try_6rd(const struct in6_addr *v6dst, struct ip_tunnel *tunnel)
static bool check_6rd(struct ip_tunnel *tunnel, const struct in6_addr *v6dst,
__be32 *v4dst)
{
__be32 dst = 0;

#ifdef CONFIG_IPV6_SIT_6RD
if (ipv6_prefix_equal(v6dst, &tunnel->ip6rd.prefix,
tunnel->ip6rd.prefixlen)) {
Expand All @@ -671,14 +689,24 @@ __be32 try_6rd(const struct in6_addr *v6dst, struct ip_tunnel *tunnel)
d |= ntohl(v6dst->s6_addr32[pbw0 + 1]) >>
(32 - pbi1);

dst = tunnel->ip6rd.relay_prefix | htonl(d);
*v4dst = tunnel->ip6rd.relay_prefix | htonl(d);
return true;
}
#else
if (v6dst->s6_addr16[0] == htons(0x2002)) {
/* 6to4 v6 addr has 16 bits prefix, 32 v4addr, 16 SLA, ... */
memcpy(&dst, &v6dst->s6_addr16[1], 4);
memcpy(v4dst, &v6dst->s6_addr16[1], 4);
return true;
}
#endif
return false;
}

static inline __be32 try_6rd(struct ip_tunnel *tunnel,
const struct in6_addr *v6dst)
{
__be32 dst = 0;
check_6rd(tunnel, v6dst, &dst);
return dst;
}

Expand Down Expand Up @@ -739,7 +767,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
}

if (!dst)
dst = try_6rd(&iph6->daddr, tunnel);
dst = try_6rd(tunnel, &iph6->daddr);

if (!dst) {
struct neighbour *neigh = NULL;
Expand Down

0 comments on commit bf25b36

Please sign in to comment.