Пример #1
0
static ssize_t led_device_name_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	struct led_netdev_data *trigger_data = led_cdev->trigger_data;

	if (size >= IFNAMSIZ)
		return -EINVAL;

	cancel_delayed_work_sync(&trigger_data->work);

	spin_lock_bh(&trigger_data->lock);

	strcpy(trigger_data->device_name, buf);
	if (size > 0 && trigger_data->device_name[size-1] == '\n')
		trigger_data->device_name[size-1] = 0;
	trigger_data->link_up = 0;
	trigger_data->last_activity = 0;

	if (trigger_data->device_name[0] != 0) {
		/* check for existing device to update from */
		trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name);
		if (trigger_data->net_dev != NULL)
			trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0;
	}

	set_baseline_state(trigger_data);
	spin_unlock_bh(&trigger_data->lock);

	return size;
}
Пример #2
0
static ssize_t led_device_name_store(struct device *dev,
		struct device_attribute *attr, const char *buf, size_t size)
{
	struct led_classdev *led_cdev = dev_get_drvdata(dev);
	struct led_netdev_data *trigger_data = led_cdev->trigger_data;

	if (size < 0 || size >= IFNAMSIZ)
		return -EINVAL;

	write_lock(&trigger_data->lock);

	strcpy(trigger_data->device_name, buf);
	if (size > 0 && trigger_data->device_name[size-1] == '\n')
		trigger_data->device_name[size-1] = 0;

	if (trigger_data->device_name[0] != 0) {
		/* check for existing device to update from */
		trigger_data->net_dev = dev_get_by_name(&init_net, trigger_data->device_name);
		if (trigger_data->net_dev != NULL)
			trigger_data->link_up = (dev_get_flags(trigger_data->net_dev) & IFF_LOWER_UP) != 0;
		set_baseline_state(trigger_data); /* updates LEDs, may start timers */
	}

	write_unlock(&trigger_data->lock);
	return size;
}
Пример #3
0
static int rxe_query_port(struct ib_device *dev,
			  u8 port_num, struct ib_port_attr *attr)
{
	struct rxe_dev *rxe = to_rdev(dev);
	struct rxe_port *port;
	int rc;

	port = &rxe->port;

	/* *attr being zeroed by the caller, avoid zeroing it here */
	*attr = port->attr;

	mutex_lock(&rxe->usdev_lock);
	rc = ib_get_eth_speed(dev, port_num, &attr->active_speed,
			      &attr->active_width);

	if (attr->state == IB_PORT_ACTIVE)
		attr->phys_state = RDMA_LINK_PHYS_STATE_LINK_UP;
	else if (dev_get_flags(rxe->ndev) & IFF_UP)
		attr->phys_state = RDMA_LINK_PHYS_STATE_POLLING;
	else
		attr->phys_state = RDMA_LINK_PHYS_STATE_DISABLED;

	mutex_unlock(&rxe->usdev_lock);

	return rc;
}
Пример #4
0
static struct nlmsghdr *rtnetlink_ifinfo_prep(struct net_device *dev,
					      struct sk_buff *skb)
{
	struct ifinfomsg *r;
	struct nlmsghdr  *nlh;

	nlh = nlmsg_put(skb, 0, 0, RTM_NEWLINK, sizeof(*r), 0);
	if (!nlh)
		return NULL;

	r = nlmsg_data(nlh);
	r->ifi_family = AF_UNSPEC;
	r->__ifi_pad = 0;
	r->ifi_type = dev->type;
	r->ifi_index = dev->ifindex;
	r->ifi_flags = dev_get_flags(dev);
	r->ifi_change = 0;	/* Wireless changes don't affect those flags */

	NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);

	return nlh;
 nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return NULL;
}
Пример #5
0
/**
 * @brief Fill a skb with an acfg event 
 *
 * @param skb
 * @param dev
 * @param type
 * @param event
 *
 * @return
 */
static
int ev_fill_info(struct sk_buff * skb, struct net_device *dev, \
                 int type, acfg_os_event_t  *event)
{
    struct ifinfomsg *r;
    struct nlmsghdr  *nlh;

    nlh = nlmsg_put(skb, 0, 0, type, sizeof(*r), 0);
    if (nlh == NULL)
        return -EMSGSIZE;

    r = nlmsg_data(nlh);
    r->ifi_family = AF_UNSPEC;
    r->__ifi_pad = 0;
    r->ifi_type = dev->type;
    r->ifi_index = dev->ifindex;
    r->ifi_flags = dev_get_flags(dev);
    r->ifi_change = 0;

    NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);

    /* Add the event in the netlink packet */
    NLA_PUT(skb, IFLA_WIRELESS, sizeof(acfg_os_event_t) , event);
    return nlmsg_end(skb, nlh);

nla_put_failure:
    nlmsg_cancel(skb, nlh);
    return -EMSGSIZE;
}
Пример #6
0
/*
 * Fill a rtnetlink message with our event data.
 * Note that we propage only the specified event and don't dump the
 * current wireless config. Dumping the wireless config is far too
 * expensive (for each parameter, the driver need to query the hardware).
 */
static int rtnetlink_fill_iwinfo(struct sk_buff *skb, struct net_device *dev,
				 int type, char *event, int event_len)
{
	struct ifinfomsg *r;
	struct nlmsghdr  *nlh;

	nlh = nlmsg_put(skb, 0, 0, type, sizeof(*r), 0);
	if (nlh == NULL)
		return -EMSGSIZE;

	r = nlmsg_data(nlh);
	r->ifi_family = AF_UNSPEC;
	r->__ifi_pad = 0;
	r->ifi_type = dev->type;
	r->ifi_index = dev->ifindex;
	r->ifi_flags = dev_get_flags(dev);
	r->ifi_change = 0;	/* Wireless changes don't affect those flags */

	/* Add the wireless events in the netlink packet */
	NLA_PUT(skb, IFLA_WIRELESS, event_len, event);

	return nlmsg_end(skb, nlh);

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}
Пример #7
0
/*
 * Create one netlink message for one interface
 * Contains port and master info as well as carrier and bridge state.
 */
static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port,
			  u32 pid, u32 seq, int event, unsigned int flags)
{
	const struct net_bridge *br = port->br;
	const struct net_device *dev = port->dev;
	struct ifinfomsg *hdr;
	struct nlmsghdr *nlh;
	u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;

	br_debug(br, "br_fill_info event %d port %s master %s\n",
		     event, dev->name, br->dev->name);

	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
	if (nlh == NULL)
		return -EMSGSIZE;

	hdr = nlmsg_data(nlh);
	hdr->ifi_family = AF_BRIDGE;
	hdr->__ifi_pad = 0;
	hdr->ifi_type = dev->type;
	hdr->ifi_index = dev->ifindex;
	hdr->ifi_flags = dev_get_flags(dev);
	hdr->ifi_change = 0;

	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
	    nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) ||
	    nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
	    nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
	    (dev->addr_len &&
	     nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
	    (dev->ifindex != dev->iflink &&
	     nla_put_u32(skb, IFLA_LINK, dev->iflink)))
		goto nla_put_failure;

	if (event == RTM_NEWLINK) {
		struct nlattr *nest
			= nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);

		if (nest == NULL || br_port_fill_attrs(skb, port) < 0)
			goto nla_put_failure;
		nla_nest_end(skb, nest);
	}

	return nlmsg_end(skb, nlh);

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}
Пример #8
0
/*
 * Create one netlink message for one interface
 * Contains port and master info as well as carrier and bridge state.
 */
static int br_fill_ifinfo(struct sk_buff *skb, const struct net_bridge_port *port,
			  u32 pid, u32 seq, int event, unsigned int flags)
{
	const struct net_bridge *br = port->br;
	const struct net_device *dev = port->dev;
	struct ifinfomsg *hdr;
	struct nlmsghdr *nlh;
	u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;

	pr_debug("br_fill_info event %d port %s master %s\n",
		 event, dev->name, br->dev->name);

	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
	if (nlh == NULL)
		return -EMSGSIZE;

	hdr = nlmsg_data(nlh);
	hdr->ifi_family = AF_BRIDGE;
	hdr->__ifi_pad = 0;
	hdr->ifi_type = dev->type;
	hdr->ifi_index = dev->ifindex;
	hdr->ifi_flags = dev_get_flags(dev);
	hdr->ifi_change = 0;

	NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
	NLA_PUT_U32(skb, IFLA_MASTER, br->dev->ifindex);
	NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
	NLA_PUT_U8(skb, IFLA_OPERSTATE, operstate);

	if (dev->addr_len)
		NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);

	if (dev->ifindex != dev->iflink)
		NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);

	if (event == RTM_NEWLINK)
		NLA_PUT_U8(skb, IFLA_PROTINFO, port->state);

	return nlmsg_end(skb, nlh);

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}
Пример #9
0
/** 
 * @brief Fill a skb with an acfg event 
 * 
 * @param skb
 * @param dev
 * @param type
 * @param event
 * 
 * @return 
 */
static
int ev_fill_info(struct sk_buff * skb, struct net_device *dev, \
                                        int type, acfg_os_event_t  *event)
{
    struct ifinfomsg *r;
    struct nlmsghdr  *nlh;
    
    nlh = nlmsg_put(skb, 0, 0, type, sizeof(*r), 0);
    if (nlh == NULL)
        return -EMSGSIZE;

    if(dev != NULL) {
        r = nlmsg_data(nlh);
        r->ifi_family = AF_UNSPEC;
        r->__ifi_pad = 0;
        r->ifi_type = dev->type;
        r->ifi_index = dev->ifindex;
        r->ifi_flags = dev_get_flags(dev);
        r->ifi_change = 0;

        NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
    }
    
    /* 
     * TODO: If acfg is interested in ACFG_EV_PROBE_REQ then this needs to be
     * fixed. acfg_os_event_t doesn't contain the data for ACFG_EV_PROBE_REQ
     * now, instead its just a container. Tests with multiple clients showed 
     * that the probe request can be > 500 bytes. Currently acfg doesn't
     * use ACFG_EV_PROBE_REQ so this should work.
     */
    /* Add the event in the netlink packet */
    NLA_PUT(skb, IFLA_WIRELESS, sizeof(acfg_os_event_t) , event);
    return nlmsg_end(skb, nlh);

nla_put_failure:
    nlmsg_cancel(skb, nlh);
    return -EMSGSIZE;
}
static int rtnetlink_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
				 int type, u32 pid, u32 seq, u32 change, 
				 unsigned int flags)
{
	struct ifinfomsg *r;
	struct nlmsghdr  *nlh;
	unsigned char	 *b = skb->tail;

	nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*r), flags);
	r = NLMSG_DATA(nlh);
	r->ifi_family = AF_UNSPEC;
	r->__ifi_pad = 0;
	r->ifi_type = dev->type;
	r->ifi_index = dev->ifindex;
	r->ifi_flags = dev_get_flags(dev);
	r->ifi_change = change;

	RTA_PUT(skb, IFLA_IFNAME, strlen(dev->name)+1, dev->name);

	if (1) {
		u32 txqlen = dev->tx_queue_len;
		RTA_PUT(skb, IFLA_TXQLEN, sizeof(txqlen), &txqlen);
	}

	if (1) {
		u32 weight = dev->weight;
		RTA_PUT(skb, IFLA_WEIGHT, sizeof(weight), &weight);
	}

	if (1) {
		struct rtnl_link_ifmap map = {
			.mem_start   = dev->mem_start,
			.mem_end     = dev->mem_end,
			.base_addr   = dev->base_addr,
			.irq         = dev->irq,
			.dma         = dev->dma,
			.port        = dev->if_port,
		};
		RTA_PUT(skb, IFLA_MAP, sizeof(map), &map);
	}

	if (dev->addr_len) {
		RTA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
		RTA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
	}

	if (1) {
		u32 mtu = dev->mtu;
		RTA_PUT(skb, IFLA_MTU, sizeof(mtu), &mtu);
	}

	if (dev->ifindex != dev->iflink) {
		u32 iflink = dev->iflink;
		RTA_PUT(skb, IFLA_LINK, sizeof(iflink), &iflink);
	}

	if (dev->qdisc_sleeping)
		RTA_PUT(skb, IFLA_QDISC,
			strlen(dev->qdisc_sleeping->ops->id) + 1,
			dev->qdisc_sleeping->ops->id);
	
	if (dev->master) {
		u32 master = dev->master->ifindex;
		RTA_PUT(skb, IFLA_MASTER, sizeof(master), &master);
	}

	if (dev->get_stats) {
		unsigned long *stats = (unsigned long*)dev->get_stats(dev);
		if (stats) {
			struct rtattr  *a;
			__u32	       *s;
			int		i;
			int		n = sizeof(struct rtnl_link_stats)/4;

			a = __RTA_PUT(skb, IFLA_STATS, n*4);
			s = RTA_DATA(a);
			for (i=0; i<n; i++)
				s[i] = stats[i];
		}
	}
	nlh->nlmsg_len = skb->tail - b;
	return skb->len;

nlmsg_failure:
rtattr_failure:
	skb_trim(skb, b - skb->data);
	return -1;
}

static int rtnetlink_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
{
	int idx;
	int s_idx = cb->args[0];
	struct net_device *dev;

	read_lock(&dev_base_lock);
	for (dev=dev_base, idx=0; dev; dev = dev->next, idx++) {
		if (idx < s_idx)
			continue;
		if (rtnetlink_fill_ifinfo(skb, dev, RTM_NEWLINK,
					  NETLINK_CB(cb->skb).pid,
					  cb->nlh->nlmsg_seq, 0,
					  NLM_F_MULTI) <= 0)
			break;
	}
	read_unlock(&dev_base_lock);
	cb->args[0] = idx;

	return skb->len;
}
Пример #11
0
int ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
	struct sockaddr_in6	*usin = (struct sockaddr_in6 *) uaddr;
	struct inet_sock      	*inet = inet_sk(sk);
	struct ipv6_pinfo      	*np = inet6_sk(sk);
	struct in6_addr		*daddr, *final_p, final;
	struct dst_entry	*dst;
	struct flowi6		fl6;
	struct ip6_flowlabel	*flowlabel = NULL;
	struct ipv6_txoptions   *opt;
	int			addr_type;
	int			err;

	if (usin->sin6_family == AF_INET) {
		if (__ipv6_only_sock(sk))
			return -EAFNOSUPPORT;
		err = ip4_datagram_connect(sk, uaddr, addr_len);
		goto ipv4_connected;
	}

	if (addr_len < SIN6_LEN_RFC2133)
		return -EINVAL;

	if (usin->sin6_family != AF_INET6)
		return -EAFNOSUPPORT;

	memset(&fl6, 0, sizeof(fl6));
	if (np->sndflow) {
		fl6.flowlabel = usin->sin6_flowinfo&IPV6_FLOWINFO_MASK;
		if (fl6.flowlabel&IPV6_FLOWLABEL_MASK) {
			flowlabel = fl6_sock_lookup(sk, fl6.flowlabel);
			if (flowlabel == NULL)
				return -EINVAL;
			ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst);
		}
	}

	addr_type = ipv6_addr_type(&usin->sin6_addr);

	if (addr_type == IPV6_ADDR_ANY) {
		/*
		 *	connect to self
		 */
		usin->sin6_addr.s6_addr[15] = 0x01;
	}

	daddr = &usin->sin6_addr;

	if (addr_type == IPV6_ADDR_MAPPED) {
		struct sockaddr_in sin;

		if (__ipv6_only_sock(sk)) {
			err = -ENETUNREACH;
			goto out;
		}
		sin.sin_family = AF_INET;
		sin.sin_addr.s_addr = daddr->s6_addr32[3];
		sin.sin_port = usin->sin6_port;

		err = ip4_datagram_connect(sk,
					   (struct sockaddr*) &sin,
					   sizeof(sin));

ipv4_connected:
		if (err)
			goto out;

		ipv6_addr_set_v4mapped(inet->inet_daddr, &np->daddr);

		if (ipv6_addr_any(&np->saddr) ||
		    ipv6_mapped_addr_any(&np->saddr))
			ipv6_addr_set_v4mapped(inet->inet_saddr, &np->saddr);

		if (ipv6_addr_any(&np->rcv_saddr) ||
		    ipv6_mapped_addr_any(&np->rcv_saddr)) {
			ipv6_addr_set_v4mapped(inet->inet_rcv_saddr,
					       &np->rcv_saddr);
			if (sk->sk_prot->rehash)
				sk->sk_prot->rehash(sk);
		}

		goto out;
	}

	if (addr_type&IPV6_ADDR_LINKLOCAL) {
		if (addr_len >= sizeof(struct sockaddr_in6) &&
		    usin->sin6_scope_id) {
			if (sk->sk_bound_dev_if &&
			    sk->sk_bound_dev_if != usin->sin6_scope_id) {
				err = -EINVAL;
				goto out;
			}
			sk->sk_bound_dev_if = usin->sin6_scope_id;
		}

		if (!sk->sk_bound_dev_if && (addr_type & IPV6_ADDR_MULTICAST))
			sk->sk_bound_dev_if = np->mcast_oif;

		if (!sk->sk_bound_dev_if) {
		}
		/* Connect to link-local address requires an interface */
		if (!sk->sk_bound_dev_if) {
#ifdef MY_ABC_HERE
			unsigned flags;
			struct net_device *dev = NULL;
			for_each_netdev(sock_net(sk), dev) {
				flags = dev_get_flags(dev);
				if((flags & IFF_RUNNING) && 
				 !(flags & (IFF_LOOPBACK | IFF_SLAVE))) {
					sk->sk_bound_dev_if = dev->ifindex;
					break;
				}
			}
			if(!sk->sk_bound_dev_if) {
				err = -EINVAL;
				goto out;
			}
#else
			err = -EINVAL;
			goto out;
#endif
		}
Пример #12
0
unsigned ovs_netdev_get_dev_flags(const struct vport *vport)
{
	const struct netdev_vport *netdev_vport = netdev_vport_priv(vport);
	return dev_get_flags(netdev_vport->dev);
}
Пример #13
0
/*
 * Create one netlink message for one interface
 * Contains port and master info as well as carrier and bridge state.
 */
static int br_fill_ifinfo(struct sk_buff *skb,
			  const struct net_bridge_port *port,
			  u32 pid, u32 seq, int event, unsigned int flags,
			  u32 filter_mask, const struct net_device *dev)
{
	const struct net_bridge *br;
	struct ifinfomsg *hdr;
	struct nlmsghdr *nlh;
	u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;

	if (port)
		br = port->br;
	else
		br = netdev_priv(dev);

	br_debug(br, "br_fill_info event %d port %s master %s\n",
		     event, dev->name, br->dev->name);

	nlh = nlmsg_put(skb, pid, seq, event, sizeof(*hdr), flags);
	if (nlh == NULL)
		return -EMSGSIZE;

	hdr = nlmsg_data(nlh);
	hdr->ifi_family = AF_BRIDGE;
	hdr->__ifi_pad = 0;
	hdr->ifi_type = dev->type;
	hdr->ifi_index = dev->ifindex;
	hdr->ifi_flags = dev_get_flags(dev);
	hdr->ifi_change = 0;

	if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
	    nla_put_u32(skb, IFLA_MASTER, br->dev->ifindex) ||
	    nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
	    nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
	    (dev->addr_len &&
	     nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
	    (dev->ifindex != dev->iflink &&
	     nla_put_u32(skb, IFLA_LINK, dev->iflink)))
		goto nla_put_failure;

	if (event == RTM_NEWLINK && port) {
		struct nlattr *nest
			= nla_nest_start(skb, IFLA_PROTINFO | NLA_F_NESTED);

		if (nest == NULL || br_port_fill_attrs(skb, port) < 0)
			goto nla_put_failure;
		nla_nest_end(skb, nest);
	}

	/* Check if  the VID information is requested */
	if (filter_mask & RTEXT_FILTER_BRVLAN) {
		struct nlattr *af;
		const struct net_port_vlans *pv;
		struct bridge_vlan_info vinfo;
		u16 vid;
		u16 pvid;

		if (port)
			pv = nbp_get_vlan_info(port);
		else
			pv = br_get_vlan_info(br);

		if (!pv || bitmap_empty(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN))
			goto done;

		af = nla_nest_start(skb, IFLA_AF_SPEC);
		if (!af)
			goto nla_put_failure;

		pvid = br_get_pvid(pv);
		for (vid = find_first_bit(pv->vlan_bitmap, BR_VLAN_BITMAP_LEN);
		     vid < BR_VLAN_BITMAP_LEN;
		     vid = find_next_bit(pv->vlan_bitmap,
					 BR_VLAN_BITMAP_LEN, vid+1)) {
			vinfo.vid = vid;
			vinfo.flags = 0;
			if (vid == pvid)
				vinfo.flags |= BRIDGE_VLAN_INFO_PVID;

			if (test_bit(vid, pv->untagged_bitmap))
				vinfo.flags |= BRIDGE_VLAN_INFO_UNTAGGED;

			if (nla_put(skb, IFLA_BRIDGE_VLAN_INFO,
				    sizeof(vinfo), &vinfo))
				goto nla_put_failure;
		}

		nla_nest_end(skb, af);
	}

done:
	return nlmsg_end(skb, nlh);

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}
Пример #14
0
int
omx_net_init(void)
{
	int ret = 0;

	omx_shared_fake_iface = kzalloc(sizeof(struct omx_iface), GFP_KERNEL);
	if (!omx_shared_fake_iface) {
                printk(KERN_ERR "Open-MX: Failed to the fake iface for shared communication counters\n");
                ret = -ENOMEM;
                goto out;
        }

	omx_ifaces = kzalloc(omx_iface_max * sizeof(struct omx_iface *), GFP_KERNEL);
	if (!omx_ifaces) {
		printk(KERN_ERR "Open-MX: failed to allocate interface array\n");
		ret = -ENOMEM;
		goto out_with_shared_fake_iface;
	}

	ret = register_netdevice_notifier(&omx_netdevice_notifier);
	if (ret < 0) {
		printk(KERN_ERR "Open-MX: failed to register netdevice notifier\n");
		goto out_with_ifaces;
	}

	omx_pkt_types_init();
	dev_add_pack(&omx_pt);

	if (omx_delayed_ifnames && strcmp(omx_delayed_ifnames, "all")) {
		/* attach ifaces whose name are in ifnames (limited to omx_iface_max) */
		printk(KERN_INFO "Open-MX: attaching interfaces listed in '%s'...\n", omx_delayed_ifnames);

		/* module parameter values are guaranteed to be \0-terminated */
		omx_ifaces_store(omx_delayed_ifnames);
		kfree(omx_delayed_ifnames);

	} else {
		/* attach everything ethernet/up/large-mtu (limited to omx_iface_max) */
		struct net_device * ifp;

		printk(KERN_INFO "Open-MX: attaching all valid interfaces...\n");

		read_lock(&dev_base_lock);
		omx_for_each_netdev(ifp) {
			/* check that it is an Ethernet device, that it is up, and that the MTU is large enough */
			if (ifp->type != ARPHRD_ETHER) {
				printk(KERN_INFO "Open-MX: not attaching non-Ethernet interface '%s' by default\n",
				       ifp->name);
				continue;
			} else if (!(dev_get_flags(ifp) & IFF_UP)) {
				printk(KERN_INFO "Open-MX: not attaching non-up interface '%s' by default\n",
				       ifp->name);
				continue;
			} else if (ifp->mtu < OMX_MTU) {
				printk(KERN_INFO "Open-MX: not attaching interface '%s' with small MTU %d by default\n",
				       ifp->name, ifp->mtu);
				continue;
			}

			dev_hold(ifp);
			if (omx_iface_attach(ifp) < 0) {
				dev_put(ifp);
				break;
			}
		}
		read_unlock(&dev_base_lock);
	}

	printk(KERN_INFO "Open-MX: attached %d interfaces\n", omx_iface_nr);
	return 0;

 out_with_ifaces:
	kfree(omx_ifaces);
 out_with_shared_fake_iface:
	kfree(omx_shared_fake_iface);
 out:
	return ret;
}
Пример #15
0
/*
 * Return the address and name of an iface.
 */
int
omx_iface_get_info(uint32_t board_index, struct omx_board_info *info)
{
	struct omx_iface * iface;
	struct net_device * ifp;
	unsigned rx_coalesce;
	int ret;

	BUILD_BUG_ON(OMX_IF_NAMESIZE != IFNAMSIZ);

	info->drivername[0] = '\0';

	rcu_read_lock();

	if (board_index == OMX_SHARED_FAKE_IFACE_INDEX) {
		info->addr = 0;
		info->numa_node = -1;
		strncpy(info->ifacename, "fake", OMX_IF_NAMESIZE);
		info->ifacename[OMX_IF_NAMESIZE-1] = '\0';
		strncpy(info->hostname, "Shared Communication", OMX_HOSTNAMELEN_MAX);
		info->hostname[OMX_HOSTNAMELEN_MAX-1] = '\0';

	} else {
#ifdef CONFIG_PCI
		struct device *dev;
#endif

		ret = -EINVAL;
		if (board_index >= omx_iface_max)
			goto out_with_lock;

		iface = rcu_dereference(omx_ifaces[board_index]);
		if (!iface)
			goto out_with_lock;

		ifp = iface->eth_ifp;

		info->addr = iface->peer.board_addr;
		info->numa_node = omx_ifp_node(iface->eth_ifp);
		strncpy(info->ifacename, ifp->name, OMX_IF_NAMESIZE);
		info->ifacename[OMX_IF_NAMESIZE-1] = '\0';
		strncpy(info->hostname, iface->peer.hostname, OMX_HOSTNAMELEN_MAX);
		info->hostname[OMX_HOSTNAMELEN_MAX-1] = '\0';

		info->mtu = ifp->mtu;
		info->status = 0;
		if (!(dev_get_flags(ifp) & IFF_UP))
			info->status |= OMX_BOARD_INFO_STATUS_DOWN;
		if (ifp->mtu < OMX_MTU)
                	info->status |= OMX_BOARD_INFO_STATUS_BAD_MTU;
		if (!omx_iface_get_rx_coalesce(ifp, &rx_coalesce)
		    && rx_coalesce >= OMX_IFACE_RX_USECS_WARN_MIN)
			info->status |= OMX_BOARD_INFO_STATUS_HIGH_INTRCOAL;

#ifdef CONFIG_PCI
		dev = omx_ifp_to_dev(ifp);
		if (dev && dev->bus == &pci_bus_type) {
			struct pci_dev *pdev = to_pci_dev(dev);
			BUG_ON(!pdev->driver);
			strncpy(info->drivername, pdev->driver->name, OMX_DRIVER_NAMESIZE);
			info->drivername[OMX_DRIVER_NAMESIZE-1] = '\0';
		}
#endif
	}

	rcu_read_unlock();
	return 0;

 out_with_lock:
	rcu_read_unlock();
	return ret;
}
Пример #16
0
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
			    int type, u32 pid, u32 seq, u32 change,
			    unsigned int flags)
{
	struct ifinfomsg *ifm;
	struct nlmsghdr *nlh;

	nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
	if (nlh == NULL)
		return -EMSGSIZE;

	ifm = nlmsg_data(nlh);
	ifm->ifi_family = AF_UNSPEC;
	ifm->__ifi_pad = 0;
	ifm->ifi_type = dev->type;
	ifm->ifi_index = dev->ifindex;
	ifm->ifi_flags = dev_get_flags(dev);
	ifm->ifi_change = change;

	NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
	NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len);
	NLA_PUT_U32(skb, IFLA_WEIGHT, dev->weight);
	NLA_PUT_U8(skb, IFLA_OPERSTATE,
		   netif_running(dev) ? dev->operstate : IF_OPER_DOWN);
	NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
	NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);

	if (dev->ifindex != dev->iflink)
		NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);

	if (dev->master)
		NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);

	if (dev->qdisc_sleeping)
		NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);

	if (1) {
		struct rtnl_link_ifmap map = {
			.mem_start   = dev->mem_start,
			.mem_end     = dev->mem_end,
			.base_addr   = dev->base_addr,
			.irq         = dev->irq,
			.dma         = dev->dma,
			.port        = dev->if_port,
		};
		NLA_PUT(skb, IFLA_MAP, sizeof(map), &map);
	}

	if (dev->addr_len) {
		NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
		NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
	}

	if (dev->get_stats) {
		struct net_device_stats *stats = dev->get_stats(dev);
		if (stats) {
			struct nlattr *attr;

			attr = nla_reserve(skb, IFLA_STATS,
					   sizeof(struct rtnl_link_stats));
			if (attr == NULL)
				goto nla_put_failure;

			copy_rtnl_link_stats(nla_data(attr), stats);
		}
	}

	return nlmsg_end(skb, nlh);

nla_put_failure:
	nlmsg_cancel(skb, nlh);
	return -EMSGSIZE;
}

static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
{
	int idx;
	int s_idx = cb->args[0];
	struct net_device *dev;

	idx = 0;
	for_each_netdev(dev) {
		if (idx < s_idx)
			goto cont;
		if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
				     NETLINK_CB(cb->skb).pid,
				     cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
			break;
cont:
		idx++;
	}
	cb->args[0] = idx;

	return skb->len;
}
Пример #17
0
/*
 * Attach a new iface.
 *
 * Must be called with ifaces lock hold and with a reference onto the ifp.
 */
static int
omx_iface_attach(struct net_device * ifp)
{
	struct omx_iface * iface;
	struct device *dev;
	char *hostname;
	unsigned mtu = ifp->mtu;
	unsigned rx_coalesce;
	int ret;
	int i;

	if (omx_iface_nr == omx_iface_max) {
		printk(KERN_ERR "Open-MX: Too many interfaces already attached\n");
		ret = -EBUSY;
		goto out;
	}

	if (omx_iface_find_by_ifp(ifp)) {
		printk(KERN_ERR "Open-MX: Interface '%s' already attached\n", ifp->name);
		ret = -EBUSY;
		goto out;
	}

	for(i=0; i<omx_iface_max; i++)
		if (rcu_access_pointer(omx_ifaces[i]) == NULL)
			break;

	iface = kzalloc(sizeof(struct omx_iface), GFP_KERNEL);
	if (!iface) {
		printk(KERN_ERR "Open-MX: Failed to allocate interface as board %d\n", i);
		ret = -ENOMEM;
		goto out;
	}

	iface->reverse_peer_indexes = kmalloc(omx_peer_max * sizeof(*iface->reverse_peer_indexes), GFP_KERNEL);
	if (!iface->reverse_peer_indexes) {
		printk(KERN_ERR "Open-MX: Failed to allocate interface reverse peer index array\n");
		ret = -ENOMEM;
		goto out_with_iface;
	}

	printk(KERN_INFO "Open-MX: Attaching %sEthernet interface '%s' as #%i, MTU=%d\n",
	       (ifp->type == ARPHRD_ETHER ? "" : "non-"), ifp->name, i, mtu);

	dev = omx_ifp_to_dev(ifp);
#ifdef CONFIG_PCI
	if (dev && dev->bus == &pci_bus_type) {
		struct pci_dev *pdev = to_pci_dev(dev);

		BUG_ON(!pdev->driver);
		printk(KERN_INFO "Open-MX:   Interface '%s' is PCI device '%s' managed by driver '%s'\n",
		       ifp->name, omx_dev_name(dev), pdev->driver->name);
	}
#endif

	if (!(dev_get_flags(ifp) & IFF_UP))
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' is not up\n",
		       ifp->name);
	if (mtu < OMX_MTU)
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' MTU should be at least %d, current value %d might cause problems\n",
		       ifp->name, OMX_MTU, mtu);
	if (!omx_iface_get_rx_coalesce(ifp, &rx_coalesce)
	    && rx_coalesce >= OMX_IFACE_RX_USECS_WARN_MIN)
		printk(KERN_WARNING "Open-MX:   WARNING: Interface '%s' interrupt coalescing very high (%ldus)\n",
		       ifp->name, (unsigned long) rx_coalesce);

	hostname = kmalloc(OMX_HOSTNAMELEN_MAX, GFP_KERNEL);
	if (!hostname) {
		printk(KERN_ERR "Open-MX:   Failed to allocate interface hostname\n");
		ret = -ENOMEM;
		goto out_with_iface_reverse_indexes;
	}

	if (ifp->type == ARPHRD_LOOPBACK)
		snprintf(hostname, OMX_HOSTNAMELEN_MAX, "localhost");
	else
		snprintf(hostname, OMX_HOSTNAMELEN_MAX, "%s:%d", omx_current_utsname.nodename, i);
	hostname[OMX_HOSTNAMELEN_MAX-1] = '\0';
	iface->peer.hostname = hostname;
	iface->peer.index = OMX_UNKNOWN_REVERSE_PEER_INDEX;
	iface->peer.board_addr = omx_board_addr_from_netdevice(ifp);
	/* reverse_peer_indexes will be initialized in omx_peers_notify_iface_attach */

	iface->eth_ifp = ifp;
	iface->endpoint_nr = 0;
	iface->endpoints = kzalloc(omx_endpoint_max * sizeof(struct omx_endpoint *), GFP_KERNEL);
	if (!iface->endpoints) {
		printk(KERN_ERR "Open-MX:   Failed to allocate interface endpoint pointers\n");
		ret = -ENOMEM;
		goto out_with_iface_hostname;
	}

	omx_iface_raw_init(&iface->raw);

	kref_init(&iface->refcount);
	mutex_init(&iface->endpoints_mutex);

	/* insert in the peer table */
	ret = omx_peers_notify_iface_attach(iface);
	if (ret < 0)
		goto out_with_raw;

	iface->index = i;
	rcu_assign_pointer(omx_ifaces[i], iface);
	omx_iface_nr++;

	return 0;

 out_with_raw:
	omx_iface_raw_exit(&iface->raw);
	kfree(iface->endpoints);
 out_with_iface_hostname:
	kfree(hostname);
 out_with_iface_reverse_indexes:
	kfree(iface->reverse_peer_indexes);
 out_with_iface:
	kfree(iface);
 out:
	return ret;
}
Пример #18
0
/*
 *	Perform the SIOCxIFxxx calls, inside rcu_read_lock()
 */
static int dev_ifsioc_locked(struct net *net, struct ifreq *ifr, unsigned int cmd)
{
	int err;
	struct net_device *dev = dev_get_by_name_rcu(net, ifr->ifr_name);

	if (!dev)
		return -ENODEV;

	switch (cmd) {
	case SIOCGIFFLAGS:	/* Get interface flags */
		ifr->ifr_flags = (short) dev_get_flags(dev);
		return 0;

	case SIOCGIFMETRIC:	/* Get the metric on the interface
				   (currently unused) */
		ifr->ifr_metric = 0;
		return 0;

	case SIOCGIFMTU:	/* Get the MTU of a device */
		ifr->ifr_mtu = dev->mtu;
		return 0;

	case SIOCGIFHWADDR:
		if (!dev->addr_len)
			memset(ifr->ifr_hwaddr.sa_data, 0,
			       sizeof(ifr->ifr_hwaddr.sa_data));
		else
			memcpy(ifr->ifr_hwaddr.sa_data, dev->dev_addr,
			       min(sizeof(ifr->ifr_hwaddr.sa_data),
				   (size_t)dev->addr_len));
		ifr->ifr_hwaddr.sa_family = dev->type;
		return 0;

	case SIOCGIFSLAVE:
		err = -EINVAL;
		break;

	case SIOCGIFMAP:
		ifr->ifr_map.mem_start = dev->mem_start;
		ifr->ifr_map.mem_end   = dev->mem_end;
		ifr->ifr_map.base_addr = dev->base_addr;
		ifr->ifr_map.irq       = dev->irq;
		ifr->ifr_map.dma       = dev->dma;
		ifr->ifr_map.port      = dev->if_port;
		return 0;

	case SIOCGIFINDEX:
		ifr->ifr_ifindex = dev->ifindex;
		return 0;

	case SIOCGIFTXQLEN:
		ifr->ifr_qlen = dev->tx_queue_len;
		return 0;

	default:
		/* dev_ioctl() should ensure this case
		 * is never reached
		 */
		WARN_ON(1);
		err = -ENOTTY;
		break;

	}
	return err;
}
Пример #19
0
fhgfs_bool __NIC_fillNicAddress(struct net_device* dev, NicAddrType_t nicType, NicAddress* outAddr)
{
   struct ifreq ifr;
   struct in_device* in_dev;
   struct in_ifaddr *ifa;

   // name
   strcpy(outAddr->name, dev->name);


   // SIOCGIFFLAGS:
   // get interface flags
   ifr.ifr_flags = dev_get_flags(dev);

   if(ifr.ifr_flags & IFF_LOOPBACK)
      return fhgfs_false; // loopback interface => skip

   if(!dev->dev_addr)
   { // should probably never happen
      printk_fhgfs(KERN_NOTICE, "found interface without dev_addr: %s\n", dev->name);
      return fhgfs_false;
   }

   // SIOCGIFHWADDR:
   // get hardware address (MAC)
   if(!dev->addr_len || !dev->dev_addr)
      memset(ifr.ifr_hwaddr.sa_data, 0, sizeof(ifr.ifr_hwaddr.sa_data) );
   else
      memcpy(ifr.ifr_hwaddr.sa_data, dev->dev_addr,
             min(sizeof(ifr.ifr_hwaddr.sa_data), (size_t) dev->addr_len) );

   ifr.ifr_hwaddr.sa_family = dev->type;


   // select which hardware types to process
   // (on Linux see /usr/include/linux/if_arp.h for the whole list)
   switch(ifr.ifr_hwaddr.sa_family)
   {
      case ARPHRD_LOOPBACK:
         return fhgfs_false;

      default:
      {
         // make sure we allow SDP for IB only (because an SDP socket domain is valid for other
         // NIC types as well, but cannot connect between different NIC types
         if( (nicType == NICADDRTYPE_SDP) && (ifr.ifr_hwaddr.sa_family != ARPHRD_INFINIBAND) )
            return fhgfs_false;
      } break;
   }


   // copy nicType
   outAddr->nicType = nicType;

   // copy hardware address
   memcpy(&outAddr->hwAddr, &ifr.ifr_addr.sa_data, IFHWADDRLEN);


   // ip address
   // note: based on inet_gifconf in /net/ipv4/devinet.c

   in_dev = __in_dev_get_rtnl(dev);
   if(!in_dev)
   {
      printk_fhgfs_debug(KERN_NOTICE, "found interface without in_dev: %s\n", dev->name);
      return fhgfs_false;
   }

   ifa = in_dev->ifa_list;
   if(!ifa)
   {
      printk_fhgfs_debug(KERN_NOTICE, "found interface without ifa_list: %s\n", dev->name);
      return fhgfs_false;
   }

   outAddr->ipAddr = ifa->ifa_local; // ip address
   outAddr->broadcastAddr = ifa->ifa_broadcast; // broadcast address

   // code to read multiple addresses
   /*
   for (; ifa; ifa = ifa->ifa_next)
   {
      (*(struct sockaddr_in *)&ifr.ifr_addr).sin_family = AF_INET;
      (*(struct sockaddr_in *)&ifr.ifr_addr).sin_addr.s_addr =
                        ifa->ifa_local;
   }
   */


   // SIOCGIFMETRIC:
   // Get the metric of the interface (currently not supported by the kernel)
   ifr.ifr_metric = 0;
   outAddr->metric = ifr.ifr_metric;


   return fhgfs_true;
}