char name[IFNAMSIZ];
int err;
- if (p->name[0]) {
+ if (p->name[0])
strlcpy(name, p->name, IFNAMSIZ);
- } else {
- int i;
- for (i = 1; i < IP6_TNL_MAX; i++) {
- sprintf(name, "ip6tnl%d", i);
- if (__dev_get_by_name(&init_net, name) == NULL)
- break;
- }
- if (i == IP6_TNL_MAX)
- goto failed;
- }
+ else
+ sprintf(name, "ip6tnl%%d");
+
dev = alloc_netdev(sizeof (*t), name, ip6_tnl_dev_setup);
if (dev == NULL)
goto failed;
+ if (strchr(name, '%')) {
+ if (dev_alloc_name(dev, name) < 0)
+ goto failed_free;
+ }
+
t = netdev_priv(dev);
dev->init = ip6_tnl_dev_init;
t->parms = *p;
- if ((err = register_netdevice(dev)) < 0) {
- free_netdev(dev);
- goto failed;
- }
+ if ((err = register_netdevice(dev)) < 0)
+ goto failed_free;
+
dev_hold(dev);
ip6_tnl_link(t);
return t;
+
+failed_free:
+ free_netdev(dev);
failed:
return NULL;
}
fl.fl4_dst = eiph->saddr;
fl.fl4_tos = RT_TOS(eiph->tos);
fl.proto = IPPROTO_IPIP;
- if (ip_route_output_key(&rt, &fl))
+ if (ip_route_output_key(&init_net, &rt, &fl))
goto out;
skb2->dev = rt->u.dst.dev;
fl.fl4_dst = eiph->daddr;
fl.fl4_src = eiph->saddr;
fl.fl4_tos = eiph->tos;
- if (ip_route_output_key(&rt, &fl) ||
+ if (ip_route_output_key(&init_net, &rt, &fl) ||
rt->u.dst.dev->type != ARPHRD_TUNNEL) {
ip_rt_put(rt);
goto out;
}
+ skb2->dst = (struct dst_entry *)rt;
} else {
ip_rt_put(rt);
if (ip_route_input(skb2, eiph->daddr, eiph->saddr, eiph->tos,
struct sk_buff *skb)
{
if (t->parms.flags & IP6_TNL_F_RCV_DSCP_COPY)
- ipv6_copy_dscp(ipv6h, ipv6_hdr(skb));
+ ipv6_copy_dscp(ipv6_get_dsfield(ipv6h), ipv6_hdr(skb));
if (INET_ECN_is_ce(ipv6_get_dsfield(ipv6h)))
IP6_ECN_set_ce(ipv6_hdr(skb));
ldev = dev_get_by_index(&init_net, 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)))
+ likely(ipv6_chk_addr(&init_net, &p->laddr, ldev, 0))) &&
+ likely(!ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
ret = 1;
if (ldev)
if (p->link)
ldev = dev_get_by_index(&init_net, p->link);
- if (unlikely(!ipv6_chk_addr(&p->laddr, ldev, 0)))
+ if (unlikely(!ipv6_chk_addr(&init_net, &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)))
+ unlikely(ipv6_chk_addr(&init_net, &p->raddr, NULL, 0)))
printk(KERN_WARNING
"%s xmit: Routing loop! "
"Remote address found on this node!\n",
*(__be32*)ipv6h = fl->fl6_flowlabel | htonl(0x60000000);
dsfield = INET_ECN_encapsulate(0, dsfield);
ipv6_change_dsfield(ipv6h, ~INET_ECN_MASK, dsfield);
- ipv6h->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
ipv6h->hop_limit = t->parms.hop_limit;
ipv6h->nexthdr = proto;
ipv6_addr_copy(&ipv6h->saddr, &fl->fl6_src);
ipv6_addr_copy(&ipv6h->daddr, &fl->fl6_dst);
nf_reset(skb);
pkt_len = skb->len;
- err = NF_HOOK(PF_INET6, NF_IP6_LOCAL_OUT, skb, NULL,
- skb->dst->dev, dst_output);
+ err = ip6_local_out(skb);
if (net_xmit_eval(err) == 0) {
stats->tx_bytes += pkt_len;