static struct net_device *ipmr_reg_vif(void)
{
	struct net_device *dev;
	struct in_device *in_dev;

	dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg",
			   reg_vif_setup);

	if (dev == NULL)
		return NULL;

	if (register_netdevice(dev)) {
		free_netdev(dev);
		return NULL;
	}
	dev->iflink = 0;

	if ((in_dev = inetdev_init(dev)) == NULL)
		goto failure;

	in_dev->cnf.rp_filter = 0;

	if (dev_open(dev))
		goto failure;

	return dev;

failure:
	/* allow the register to be completed before unregistering. */
	rtnl_unlock();
	rtnl_lock();

	unregister_netdevice(dev);
	return NULL;
}
Esempio n. 2
0
static struct net_device *ipmr_reg_vif(void)
{
    struct net_device *dev;
    struct in_device *in_dev;

    dev = alloc_netdev(sizeof(struct net_device_stats), "pimreg",
                       reg_vif_setup);

    if (dev == NULL)
        return NULL;

    if (register_netdevice(dev)) {
        free_netdev(dev);
        return NULL;
    }
    dev->iflink = 0;

    if ((in_dev = inetdev_init(dev)) == NULL)
        goto failure;

    in_dev->cnf.rp_filter = 0;

    if (dev_open(dev))
        goto failure;

    return dev;

failure:
    unregister_netdevice(dev);
    return NULL;
}
Esempio n. 3
0
static
struct device *ipmr_reg_vif(struct vifctl *v)
{
	struct device  *dev;
	struct in_device *in_dev;
	int size;

	size = sizeof(*dev) + IFNAMSIZ + sizeof(struct net_device_stats);
	dev = kmalloc(size, GFP_KERNEL);
	if (!dev)
		return NULL;

	memset(dev, 0, size);

	dev->priv = dev + 1;
	dev->name = dev->priv + sizeof(struct net_device_stats);

	strcpy(dev->name, "pimreg");

	dev->type		= ARPHRD_PIMREG;
	dev->mtu		= 1500 - sizeof(struct iphdr) - 8;
	dev->flags		= IFF_NOARP;
	dev->hard_start_xmit	= reg_vif_xmit;
	dev->get_stats		= reg_vif_get_stats;

	rtnl_lock();

	if (register_netdevice(dev)) {
		rtnl_unlock();
		kfree(dev);
		return NULL;
	}
	dev->iflink = 0;

	if ((in_dev = inetdev_init(dev)) == NULL)
		goto failure;

	in_dev->cnf.rp_filter = 0;

	if (dev_open(dev))
		goto failure;

	rtnl_unlock();
	reg_dev = dev;
	return dev;

failure:
	unregister_netdevice(dev);
	rtnl_unlock();
	kfree(dev);
	return NULL;
}
Esempio n. 4
0
static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
{
    struct rtattr **rta = arg;
    struct net_device *dev;
    struct in_device *in_dev;
    struct ifaddrmsg *ifm = NLMSG_DATA(nlh);
    struct in_ifaddr *ifa;
    int rc = -EINVAL;

    ASSERT_RTNL();

    if (ifm->ifa_prefixlen > 32 || !rta[IFA_LOCAL - 1])
        goto out;

    rc = -ENODEV;
    if ((dev = __dev_get_by_index(ifm->ifa_index)) == NULL)
        goto out;

    rc = -ENOBUFS;
    if ((in_dev = __in_dev_get(dev)) == NULL) {
        in_dev = inetdev_init(dev);
        if (!in_dev)
            goto out;
    }

    if ((ifa = inet_alloc_ifa()) == NULL)
        goto out;

    if (!rta[IFA_ADDRESS - 1])
        rta[IFA_ADDRESS - 1] = rta[IFA_LOCAL - 1];
    memcpy(&ifa->ifa_local, RTA_DATA(rta[IFA_LOCAL - 1]), 4);
    memcpy(&ifa->ifa_address, RTA_DATA(rta[IFA_ADDRESS - 1]), 4);
    ifa->ifa_prefixlen = ifm->ifa_prefixlen;
    ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
    if (rta[IFA_BROADCAST - 1])
        memcpy(&ifa->ifa_broadcast,
               RTA_DATA(rta[IFA_BROADCAST - 1]), 4);
    if (rta[IFA_ANYCAST - 1])
        memcpy(&ifa->ifa_anycast, RTA_DATA(rta[IFA_ANYCAST - 1]), 4);
    ifa->ifa_flags = ifm->ifa_flags;
    ifa->ifa_scope = ifm->ifa_scope;
    in_dev_hold(in_dev);
    ifa->ifa_dev   = in_dev;
    if (rta[IFA_LABEL - 1])
        rtattr_strlcpy(ifa->ifa_label, rta[IFA_LABEL - 1], IFNAMSIZ);
    else
        memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);

    rc = inet_insert_ifa(ifa);
out:
    return rc;
}
static
struct net_device *ipmr_new_tunnel(struct vifctl *v)
{
	struct net_device  *dev;

	dev = __dev_get_by_name("tunl0");

	if (dev) {
		int err;
		struct ifreq ifr;
		mm_segment_t	oldfs;
		struct ip_tunnel_parm p;
		struct in_device  *in_dev;

		memset(&p, 0, sizeof(p));
		p.iph.daddr = v->vifc_rmt_addr.s_addr;
		p.iph.saddr = v->vifc_lcl_addr.s_addr;
		p.iph.version = 4;
		p.iph.ihl = 5;
		p.iph.protocol = IPPROTO_IPIP;
		sprintf(p.name, "dvmrp%d", v->vifc_vifi);
		ifr.ifr_ifru.ifru_data = (void*)&p;

		oldfs = get_fs(); set_fs(KERNEL_DS);
		err = dev->do_ioctl(dev, &ifr, SIOCADDTUNNEL);
		set_fs(oldfs);

		dev = NULL;

		if (err == 0 && (dev = __dev_get_by_name(p.name)) != NULL) {
			dev->flags |= IFF_MULTICAST;

			in_dev = __in_dev_get_rtnl(dev);
			if (in_dev == NULL && (in_dev = inetdev_init(dev)) == NULL)
				goto failure;
			in_dev->cnf.rp_filter = 0;

			if (dev_open(dev))
				goto failure;
		}
	}
	return dev;

failure:
	/* allow the register to be completed before unregistering. */
	rtnl_unlock();
	rtnl_lock();

	unregister_netdevice(dev);
	return NULL;
}
Esempio n. 6
0
static int inet_set_ifa(struct net_device *dev, struct in_ifaddr *ifa)
{
	struct in_device *in_dev = __in_dev_get_rtnl(dev);

	ASSERT_RTNL();

	if (!in_dev) {
		in_dev = inetdev_init(dev);
		if (!in_dev) {
			inet_free_ifa(ifa);
			return -ENOBUFS;
		}
	}
	if (ifa->ifa_dev != in_dev) {
		BUG_TRAP(!ifa->ifa_dev);
		in_dev_hold(in_dev);
		ifa->ifa_dev = in_dev;
	}
	if (LOOPBACK(ifa->ifa_local))
		ifa->ifa_scope = RT_SCOPE_HOST;
	return inet_insert_ifa(ifa);
}
Esempio n. 7
0
int rst_restore_ifaddr(struct cpt_context *ctx)
{
	struct net *net = get_exec_env()->ve_netns;
	int err;
	loff_t sec = ctx->sections[CPT_SECT_NET_IFADDR];
	loff_t endsec;
	struct cpt_section_hdr h;
	struct cpt_ifaddr_image di;
	struct net_device *dev;

	if (sec == CPT_NULL)
		return 0;

	err = ctx->pread(&h, sizeof(h), ctx, sec);
	if (err)
		return err;
	if (h.cpt_section != CPT_SECT_NET_IFADDR || h.cpt_hdrlen < sizeof(h))
		return -EINVAL;

	endsec = sec + h.cpt_next;
	sec += h.cpt_hdrlen;
	while (sec < endsec) {
		int cindex = -1;
		int err;
		err = rst_get_object(CPT_OBJ_NET_IFADDR, sec, &di, ctx);
		if (err)
			return err;
		cindex = di.cpt_index;
		rtnl_lock();
		dev = __dev_get_by_index(net, cindex);
		if (dev && di.cpt_family == AF_INET) {
			struct in_device *in_dev;
			struct in_ifaddr *ifa;
			if ((in_dev = __in_dev_get_rtnl(dev)) == NULL)
				in_dev = inetdev_init(dev);
			ifa = inet_alloc_ifa();
			if (ifa) {
				ifa->ifa_local = di.cpt_address[0];
				ifa->ifa_address = di.cpt_peer[0];
				ifa->ifa_broadcast = di.cpt_broadcast[0];
				ifa->ifa_prefixlen = di.cpt_masklen;
				ifa->ifa_mask = inet_make_mask(ifa->ifa_prefixlen);
				ifa->ifa_flags = di.cpt_flags;
				ifa->ifa_scope = di.cpt_scope;
				memcpy(ifa->ifa_label, di.cpt_label, IFNAMSIZ);
				in_dev_hold(in_dev);
				ifa->ifa_dev   = in_dev;
				err = inet_insert_ifa(ifa);
				if (err && err != -EEXIST) {
					rtnl_unlock();
					eprintk_ctx("add ifaddr err %d for %d %s\n", err, di.cpt_index, di.cpt_label);
					return err;
				}
			}
#if defined(CONFIG_IPV6) || defined (CONFIG_IPV6_MODULE)
		} else if (dev && di.cpt_family == AF_INET6) {
			__u32 prefered_lft;
			__u32 valid_lft;
			struct net *net = get_exec_env()->ve_ns->net_ns;
			prefered_lft = (di.cpt_flags & IFA_F_DEPRECATED) ?
				0 : di.cpt_prefered_lft;
			valid_lft = (di.cpt_flags & IFA_F_PERMANENT) ?
				0xFFFFFFFF : di.cpt_valid_lft;
			err = inet6_addr_add(net, dev->ifindex,
					     (struct in6_addr *)di.cpt_address,
					     di.cpt_masklen, 0,
					     prefered_lft,
					     valid_lft);
			if (err && err != -EEXIST) {
				rtnl_unlock();
				eprintk_ctx("add ifaddr err %d for %d %s\n", err, di.cpt_index, di.cpt_label);
				return err;
			}
#endif
		} else {
			rtnl_unlock();
			eprintk_ctx("unknown ifaddr 2 for %d\n", di.cpt_index);
			return -EINVAL;
		}
		rtnl_unlock();
		sec += di.cpt_next;
	}
	return 0;
}
Esempio n. 8
0
static struct in_ifaddr *rtm_to_ifaddr(struct nlmsghdr *nlh)
{
	struct nlattr *tb[IFA_MAX+1];
	struct in_ifaddr *ifa;
	struct ifaddrmsg *ifm;
	struct net_device *dev;
	struct in_device *in_dev;
	int err = -EINVAL;

	err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv4_policy);
	if (err < 0)
		goto errout;

	ifm = nlmsg_data(nlh);
	if (ifm->ifa_prefixlen > 32 || tb[IFA_LOCAL] == NULL) {
		err = -EINVAL;
		goto errout;
	}

	dev = __dev_get_by_index(ifm->ifa_index);
	if (dev == NULL) {
		err = -ENODEV;
		goto errout;
	}

	in_dev = __in_dev_get_rtnl(dev);
	if (in_dev == NULL) {
		in_dev = inetdev_init(dev);
		if (in_dev == NULL) {
			err = -ENOBUFS;
			goto errout;
		}
	}

	ifa = inet_alloc_ifa();
	if (ifa == NULL) {
		/*
		 * A potential indev allocation can be left alive, it stays
		 * assigned to its device and is destroy with it.
		 */
		err = -ENOBUFS;
		goto errout;
	}

	in_dev_hold(in_dev);

	if (tb[IFA_ADDRESS] == NULL)
		tb[IFA_ADDRESS] = tb[IFA_LOCAL];

	ifa->ifa_prefixlen = ifm->ifa_prefixlen;
	ifa->ifa_mask = inet_make_mask(ifm->ifa_prefixlen);
	ifa->ifa_flags = ifm->ifa_flags;
	ifa->ifa_scope = ifm->ifa_scope;
	ifa->ifa_dev = in_dev;

	ifa->ifa_local = nla_get_be32(tb[IFA_LOCAL]);
	ifa->ifa_address = nla_get_be32(tb[IFA_ADDRESS]);

	if (tb[IFA_BROADCAST])
		ifa->ifa_broadcast = nla_get_be32(tb[IFA_BROADCAST]);

	if (tb[IFA_ANYCAST])
		ifa->ifa_anycast = nla_get_be32(tb[IFA_ANYCAST]);

	if (tb[IFA_LABEL])
		nla_strlcpy(ifa->ifa_label, tb[IFA_LABEL], IFNAMSIZ);
	else
		memcpy(ifa->ifa_label, dev->name, IFNAMSIZ);

	return ifa;

errout:
	return ERR_PTR(err);
}