static struct ip_tunnel * ipip6_tunnel_locate(struct net *net, struct ip_tunnel_parm *parms, int create) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; struct ip_tunnel *t, **tp, *nt; struct net_device *dev; char name[IFNAMSIZ]; struct sit_net *sitn = net_generic(net, sit_net_id); for (tp = __ipip6_bucket(sitn, parms); (t = *tp) != NULL; tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr && parms->link == t->parms.link) { if (create) return NULL; else return t; } } if (!create) goto failed; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else sprintf(name, "sit%%d"); dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) return NULL; dev_net_set(dev, net); if (strchr(name, '%')) { if (dev_alloc_name(dev, name) < 0) goto failed_free; } nt = netdev_priv(dev); nt->parms = *parms; ipip6_tunnel_init(dev); if (parms->i_flags & SIT_ISATAP) dev->priv_flags |= IFF_ISATAP; if (register_netdevice(dev) < 0) goto failed_free; dev_hold(dev); ipip6_tunnel_link(sitn, nt); return nt; failed_free: free_netdev(dev); failed: return NULL; }
struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) { u32 remote = parms->iph.daddr; u32 local = parms->iph.saddr; struct ip_tunnel *t, **tp, *nt; struct net_device *dev; for (tp = __ipip6_bucket(parms); (t = *tp) != NULL; tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) return t; } if (!create) return NULL; MOD_INC_USE_COUNT; dev = kmalloc(sizeof(*dev) + sizeof(*t), GFP_KERNEL); if (dev == NULL) { MOD_DEC_USE_COUNT; return NULL; } memset(dev, 0, sizeof(*dev) + sizeof(*t)); dev->priv = (void*)(dev+1); nt = (struct ip_tunnel*)dev->priv; nt->dev = dev; dev->init = ipip6_tunnel_init; dev->features |= NETIF_F_DYNALLOC; memcpy(&nt->parms, parms, sizeof(*parms)); nt->parms.name[IFNAMSIZ-1] = '\0'; strcpy(dev->name, nt->parms.name); if (dev->name[0] == 0) { int i; for (i=1; i<100; i++) { sprintf(dev->name, "sit%d", i); if (__dev_get_by_name(dev->name) == NULL) break; } if (i==100) goto failed; memcpy(nt->parms.name, dev->name, IFNAMSIZ); } if (register_netdevice(dev) < 0) goto failed; dev_hold(dev); ipip6_tunnel_link(nt); /* Do not decrement MOD_USE_COUNT here. */ return nt; failed: kfree(dev); MOD_DEC_USE_COUNT; return NULL; }
static struct ip_tunnel * ipip6_tunnel_locate(struct ip_tunnel_parm *parms, int create) { __be32 remote = parms->iph.daddr; __be32 local = parms->iph.saddr; struct ip_tunnel *t, **tp, *nt; struct net_device *dev; char name[IFNAMSIZ]; for (tp = __ipip6_bucket(parms); (t = *tp) != NULL; tp = &t->next) { if (local == t->parms.iph.saddr && remote == t->parms.iph.daddr) return t; } if (!create) goto failed; if (parms->name[0]) strlcpy(name, parms->name, IFNAMSIZ); else { int i; for (i=1; i<100; i++) { sprintf(name, "sit%d", i); if (__dev_get_by_name(name) == NULL) break; } if (i==100) goto failed; } dev = alloc_netdev(sizeof(*t), name, ipip6_tunnel_setup); if (dev == NULL) return NULL; nt = netdev_priv(dev); dev->init = ipip6_tunnel_init; nt->parms = *parms; if (register_netdevice(dev) < 0) { free_netdev(dev); goto failed; } dev_hold(dev); ipip6_tunnel_link(nt); return nt; failed: return NULL; }