Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 41869
b: refs/heads/master
c: 09c6bbf
h: refs/heads/master
i:
  41867: bc77edd
v: v3
  • Loading branch information
Ville Nuorvala authored and David S. Miller committed Dec 3, 2006
1 parent d422a02 commit ad8e8d4
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 35 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: 567131a722ca064c917c0b06e4bcf07d47602103
refs/heads/master: 09c6bbf090ecb52c8d670fa4d5730be134a8ec8b
96 changes: 62 additions & 34 deletions trunk/net/ipv6/ip6_tunnel.c
Original file line number Diff line number Diff line change
Expand Up @@ -494,6 +494,27 @@ static inline void ip6ip6_ecn_decapsulate(struct ipv6hdr *outer_iph,
if (INET_ECN_is_ce(ipv6_get_dsfield(outer_iph)))
IP6_ECN_set_ce(inner_iph);
}
static inline int ip6_tnl_rcv_ctl(struct ip6_tnl *t)
{
struct ip6_tnl_parm *p = &t->parms;
int ret = 0;

if (p->flags & IP6_TNL_F_CAP_RCV) {
struct net_device *ldev = NULL;

if (p->link)
ldev = dev_get_by_index(p->link);

if ((ipv6_addr_is_multicast(&p->laddr) ||
likely(ipv6_chk_addr(&p->laddr, ldev, 0))) &&
likely(!ipv6_chk_addr(&p->raddr, NULL, 0)))
ret = 1;

if (ldev)
dev_put(ldev);
}
return ret;
}

/**
* ip6ip6_rcv - decapsulate IPv6 packet and retransmit it locally
Expand All @@ -518,7 +539,7 @@ ip6ip6_rcv(struct sk_buff *skb)
goto discard;
}

if (!(t->parms.flags & IP6_TNL_F_CAP_RCV)) {
if (!ip6_tnl_rcv_ctl(t)) {
t->stat.rx_dropped++;
read_unlock(&ip6ip6_lock);
goto discard;
Expand Down Expand Up @@ -597,6 +618,34 @@ ip6ip6_tnl_addr_conflict(struct ip6_tnl *t, struct ipv6hdr *hdr)
return ipv6_addr_equal(&t->parms.raddr, &hdr->saddr);
}

static inline int ip6_tnl_xmit_ctl(struct ip6_tnl *t)
{
struct ip6_tnl_parm *p = &t->parms;
int ret = 0;

if (p->flags & IP6_TNL_F_CAP_XMIT) {
struct net_device *ldev = NULL;

if (p->link)
ldev = dev_get_by_index(p->link);

if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
printk(KERN_WARNING
"%s xmit: Local address not yet configured!\n",
p->name);
else if (!ipv6_addr_is_multicast(&p->raddr) &&
unlikely(ipv6_chk_addr(&p->raddr, NULL, 0)))
printk(KERN_WARNING
"%s xmit: Routing loop! "
"Remote address found on this node!\n",
p->name);
else
ret = 1;
if (ldev)
dev_put(ldev);
}
return ret;
}
/**
* ip6ip6_tnl_xmit - encapsulate packet and send
* @skb: the outgoing socket buffer
Expand Down Expand Up @@ -634,10 +683,9 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
goto tx_err;
}
if (skb->protocol != htons(ETH_P_IPV6) ||
!(t->parms.flags & IP6_TNL_F_CAP_XMIT) ||
ip6ip6_tnl_addr_conflict(t, ipv6h)) {
!ip6_tnl_xmit_ctl(t) || ip6ip6_tnl_addr_conflict(t, ipv6h))
goto tx_err;
}

if ((offset = parse_tlv_tnl_enc_lim(skb, skb->nh.raw)) > 0) {
struct ipv6_tlv_tnl_enc_lim *tel;
tel = (struct ipv6_tlv_tnl_enc_lim *) &skb->nh.raw[offset];
Expand Down Expand Up @@ -768,39 +816,19 @@ ip6ip6_tnl_xmit(struct sk_buff *skb, struct net_device *dev)
static void ip6_tnl_set_cap(struct ip6_tnl *t)
{
struct ip6_tnl_parm *p = &t->parms;
struct in6_addr *laddr = &p->laddr;
struct in6_addr *raddr = &p->raddr;
int ltype = ipv6_addr_type(laddr);
int rtype = ipv6_addr_type(raddr);
int ltype = ipv6_addr_type(&p->laddr);
int rtype = ipv6_addr_type(&p->raddr);

p->flags &= ~(IP6_TNL_F_CAP_XMIT|IP6_TNL_F_CAP_RCV);

if (ltype != IPV6_ADDR_ANY && rtype != IPV6_ADDR_ANY &&
((ltype|rtype) &
(IPV6_ADDR_UNICAST|
IPV6_ADDR_LOOPBACK|IPV6_ADDR_LINKLOCAL|
IPV6_ADDR_MAPPED|IPV6_ADDR_RESERVED)) == IPV6_ADDR_UNICAST) {
struct net_device *ldev = NULL;
int l_ok = 1;
int r_ok = 1;

if (p->link)
ldev = dev_get_by_index(p->link);

if (ltype&IPV6_ADDR_UNICAST && !ipv6_chk_addr(laddr, ldev, 0))
l_ok = 0;

if (rtype&IPV6_ADDR_UNICAST && ipv6_chk_addr(raddr, NULL, 0))
r_ok = 0;

if (l_ok && r_ok) {
if (ltype&IPV6_ADDR_UNICAST)
p->flags |= IP6_TNL_F_CAP_XMIT;
if (rtype&IPV6_ADDR_UNICAST)
p->flags |= IP6_TNL_F_CAP_RCV;
}
if (ldev)
dev_put(ldev);
if (ltype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
rtype & (IPV6_ADDR_UNICAST|IPV6_ADDR_MULTICAST) &&
!((ltype|rtype) & IPV6_ADDR_LOOPBACK) &&
!((ltype|rtype) & IPV6_ADDR_LINKLOCAL)) {
if (ltype&IPV6_ADDR_UNICAST)
p->flags |= IP6_TNL_F_CAP_XMIT;
if (rtype&IPV6_ADDR_UNICAST)
p->flags |= IP6_TNL_F_CAP_RCV;
}
}

Expand Down

0 comments on commit ad8e8d4

Please sign in to comment.