Ejemplo n.º 1
0
static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
{
	hdlc_device *hdlc = dev_to_hdlc(dev);
	int result;

	switch (ifr->ifr_settings.type) {
	case IF_GET_PROTO:
		if (dev_to_hdlc(dev)->proto != &proto)
			return -EINVAL;
		ifr->ifr_settings.type = IF_PROTO_X25;
		return 0; /* return protocol only, no settable parameters */

	case IF_PROTO_X25:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;

		if (dev->flags & IFF_UP)
			return -EBUSY;

		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
		if (result)
			return result;

		if ((result = attach_hdlc_protocol(dev, &proto, 0)))
			return result;
		dev->type = ARPHRD_X25;
		netif_dormant_off(dev);
		return 0;
	}

	return -EINVAL;
}
Ejemplo n.º 2
0
Archivo: net.c Proyecto: avagin/linux
static int most_nd_open(struct net_device *dev)
{
	struct net_dev_context *nd = netdev_priv(dev);
	int ret = 0;

	mutex_lock(&probe_disc_mt);

	if (most_start_channel(nd->iface, nd->rx.ch_id, &comp)) {
		netdev_err(dev, "most_start_channel() failed\n");
		ret = -EBUSY;
		goto unlock;
	}

	if (most_start_channel(nd->iface, nd->tx.ch_id, &comp)) {
		netdev_err(dev, "most_start_channel() failed\n");
		most_stop_channel(nd->iface, nd->rx.ch_id, &comp);
		ret = -EBUSY;
		goto unlock;
	}

	netif_carrier_off(dev);
	if (is_valid_ether_addr(dev->dev_addr))
		netif_dormant_off(dev);
	else
		netif_dormant_on(dev);
	netif_wake_queue(dev);
	if (nd->iface->request_netinfo)
		nd->iface->request_netinfo(nd->iface, nd->tx.ch_id, on_netinfo);

unlock:
	mutex_unlock(&probe_disc_mt);
	return ret;
}
Ejemplo n.º 3
0
Archivo: net.c Proyecto: avagin/linux
/**
 * on_netinfo - callback for HDM to be informed about HW's MAC
 * @param iface - most interface instance
 * @param link_stat - link status
 * @param mac_addr - MAC address
 */
static void on_netinfo(struct most_interface *iface,
		       unsigned char link_stat, unsigned char *mac_addr)
{
	struct net_dev_context *nd;
	struct net_device *dev;
	const u8 *m = mac_addr;

	nd = get_net_dev_hold(iface);
	if (!nd)
		return;

	dev = nd->dev;

	if (link_stat)
		netif_carrier_on(dev);
	else
		netif_carrier_off(dev);

	if (m && is_valid_ether_addr(m)) {
		if (!is_valid_ether_addr(dev->dev_addr)) {
			netdev_info(dev, "set mac %02x-%02x-%02x-%02x-%02x-%02x\n",
				    m[0], m[1], m[2], m[3], m[4], m[5]);
			ether_addr_copy(dev->dev_addr, m);
			netif_dormant_off(dev);
		} else if (!ether_addr_equal(dev->dev_addr, m)) {
			netdev_warn(dev, "reject mac %02x-%02x-%02x-%02x-%02x-%02x\n",
				    m[0], m[1], m[2], m[3], m[4], m[5]);
		}
	}

	dev_put(nd->dev);
}
Ejemplo n.º 4
0
/* opa_vnic_process_vema_config - process vema configuration updates */
void opa_vnic_process_vema_config(struct opa_vnic_adapter *adapter)
{
	struct __opa_veswport_info *info = &adapter->info;
	struct rdma_netdev *rn = netdev_priv(adapter->netdev);
	u8 port_num[OPA_VESW_MAX_NUM_DEF_PORT] = { 0 };
	struct net_device *netdev = adapter->netdev;
	u8 i, port_count = 0;
	u16 port_mask;

	/* If the base_mac_addr is changed, update the interface mac address */
	if (memcmp(info->vport.base_mac_addr, adapter->vema_mac_addr,
		   ARRAY_SIZE(info->vport.base_mac_addr))) {
		struct sockaddr saddr;

		memcpy(saddr.sa_data, info->vport.base_mac_addr,
		       ARRAY_SIZE(info->vport.base_mac_addr));
		mutex_lock(&adapter->lock);
		eth_mac_addr(netdev, &saddr);
		memcpy(adapter->vema_mac_addr,
		       info->vport.base_mac_addr, ETH_ALEN);
		mutex_unlock(&adapter->lock);
	}

	rn->set_id(netdev, info->vesw.vesw_id);

	/* Handle MTU limit change */
	rtnl_lock();
	netdev->max_mtu = max_t(unsigned int, info->vesw.eth_mtu_non_vlan,
				netdev->min_mtu);
	if (netdev->mtu > netdev->max_mtu)
		dev_set_mtu(netdev, netdev->max_mtu);
	rtnl_unlock();

	/* Update flow to default port redirection table */
	port_mask = info->vesw.def_port_mask;
	for (i = 0; i < OPA_VESW_MAX_NUM_DEF_PORT; i++) {
		if (port_mask & 1)
			port_num[port_count++] = i;
		port_mask >>= 1;
	}

	/*
	 * Build the flow table. Flow table is required when destination LID
	 * is not available. Up to OPA_VNIC_FLOW_TBL_SIZE flows supported.
	 * Each flow need a default port number to get its dlid from the
	 * u_ucast_dlid array.
	 */
	for (i = 0; i < OPA_VNIC_FLOW_TBL_SIZE; i++)
		adapter->flow_tbl[i] = port_count ? port_num[i % port_count] :
						    OPA_VNIC_INVALID_PORT;

	/* Operational state can only be DROP_ALL or FORWARDING */
	if (info->vport.config_state == OPA_VNIC_STATE_FORWARDING) {
		info->vport.oper_state = OPA_VNIC_STATE_FORWARDING;
		netif_dormant_off(netdev);
	} else {
		info->vport.oper_state = OPA_VNIC_STATE_DROP_ALL;
		netif_dormant_on(netdev);
	}
}
Ejemplo n.º 5
0
static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
{
	raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
	const size_t size = sizeof(raw_hdlc_proto);
	raw_hdlc_proto new_settings;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	int result, old_qlen;

	switch (ifr->ifr_settings.type) {
	case IF_GET_PROTO:
		if (dev_to_hdlc(dev)->proto != &proto)
			return -EINVAL;
		ifr->ifr_settings.type = IF_PROTO_HDLC_ETH;
		if (ifr->ifr_settings.size < size) {
			ifr->ifr_settings.size = size; /* data size wanted */
			return -ENOBUFS;
		}
		if (copy_to_user(raw_s, hdlc->state, size))
			return -EFAULT;
		return 0;

	case IF_PROTO_HDLC_ETH:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;

		if (dev->flags & IFF_UP)
			return -EBUSY;

		if (copy_from_user(&new_settings, raw_s, size))
			return -EFAULT;

		if (new_settings.encoding == ENCODING_DEFAULT)
			new_settings.encoding = ENCODING_NRZ;

		if (new_settings.parity == PARITY_DEFAULT)
			new_settings.parity = PARITY_CRC16_PR1_CCITT;

		result = hdlc->attach(dev, new_settings.encoding,
				      new_settings.parity);
		if (result)
			return result;

		result = attach_hdlc_protocol(dev, &proto,
					      sizeof(raw_hdlc_proto));
		if (result)
			return result;
		memcpy(hdlc->state, &new_settings, size);
		old_qlen = dev->tx_queue_len;
		ether_setup(dev);
		dev->tx_queue_len = old_qlen;
		random_ether_addr(dev->dev_addr);
		netif_dormant_off(dev);
		return 0;
	}

	return -EINVAL;
}
Ejemplo n.º 6
0
int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
{
	raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
	const size_t size = sizeof(raw_hdlc_proto);
	raw_hdlc_proto new_settings;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	int result;

	switch (ifr->ifr_settings.type) {
	case IF_GET_PROTO:
		ifr->ifr_settings.type = IF_PROTO_HDLC;
		if (ifr->ifr_settings.size < size) {
			ifr->ifr_settings.size = size; /* data size wanted */
			return -ENOBUFS;
		}
		if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size))
			return -EFAULT;
		return 0;

	case IF_PROTO_HDLC:
		if (!capable(CAP_NET_ADMIN))
			return -EPERM;

		if (dev->flags & IFF_UP)
			return -EBUSY;

		if (copy_from_user(&new_settings, raw_s, size))
			return -EFAULT;

		if (new_settings.encoding == ENCODING_DEFAULT)
			new_settings.encoding = ENCODING_NRZ;

		if (new_settings.parity == PARITY_DEFAULT)
			new_settings.parity = PARITY_CRC16_PR1_CCITT;

		result = hdlc->attach(dev, new_settings.encoding,
				      new_settings.parity);
		if (result)
			return result;

		hdlc_proto_detach(hdlc);
		memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size);
		memset(&hdlc->proto, 0, sizeof(hdlc->proto));

		hdlc->proto.type_trans = raw_type_trans;
		hdlc->proto.id = IF_PROTO_HDLC;
		dev->hard_start_xmit = hdlc->xmit;
		dev->hard_header = NULL;
		dev->type = ARPHRD_RAWHDLC;
		dev->flags = IFF_POINTOPOINT | IFF_NOARP;
		dev->addr_len = 0;
		netif_dormant_off(dev);
		return 0;
	}

	return -EINVAL;
}
Ejemplo n.º 7
0
static void vlan_transfer_operstate(const struct net_device *dev, struct net_device *vlandev)
{
	/* Have to respect userspace enforced dormant state
	 * of real device, also must allow supplicant running
	 * on VLAN device
	 */
	if (dev->operstate == IF_OPER_DORMANT)
		netif_dormant_on(vlandev);
	else
		netif_dormant_off(vlandev);

	if (netif_carrier_ok(dev)) {
		if (!netif_carrier_ok(vlandev))
			netif_carrier_on(vlandev);
	} else {
		if (netif_carrier_ok(vlandev))
			netif_carrier_off(vlandev);
	}
}
Ejemplo n.º 8
0
int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
{
	hdlc_device *hdlc = dev_to_hdlc(dev);
	int result;

	switch (ifr->ifr_settings.type) {
	case IF_GET_PROTO:
		ifr->ifr_settings.type = IF_PROTO_X25;
		return 0; /* return protocol only, no settable parameters */

	case IF_PROTO_X25:
		if(!capable(CAP_NET_ADMIN))
			return -EPERM;

		if(dev->flags & IFF_UP)
			return -EBUSY;

		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
		if (result)
			return result;

		hdlc_proto_detach(hdlc);
		memset(&hdlc->proto, 0, sizeof(hdlc->proto));

		hdlc->proto.open = x25_open;
		hdlc->proto.close = x25_close;
		hdlc->proto.netif_rx = x25_rx;
		hdlc->proto.type_trans = NULL;
		hdlc->proto.id = IF_PROTO_X25;
		dev->hard_start_xmit = x25_xmit;
		dev->hard_header = NULL;
		dev->type = ARPHRD_X25;
		dev->addr_len = 0;
		netif_dormant_off(dev);
		return 0;
	}

	return -EINVAL;
}
Ejemplo n.º 9
0
static int cisco_rx(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	struct cisco_state *st = state(hdlc);
	struct hdlc_header *data = (struct hdlc_header*)skb->data;
	struct cisco_packet *cisco_data;
	struct in_device *in_dev;
	__be32 addr, mask;
	u32 ack;

	if (skb->len < sizeof(struct hdlc_header))
		goto rx_error;

	if (data->address != CISCO_MULTICAST &&
	    data->address != CISCO_UNICAST)
		goto rx_error;

	switch (ntohs(data->protocol)) {
	case CISCO_SYS_INFO:
		/* Packet is not needed, drop it. */
		dev_kfree_skb_any(skb);
		return NET_RX_SUCCESS;

	case CISCO_KEEPALIVE:
		if ((skb->len != sizeof(struct hdlc_header) +
		     CISCO_PACKET_LEN) &&
		    (skb->len != sizeof(struct hdlc_header) +
		     CISCO_BIG_PACKET_LEN)) {
			netdev_info(dev, "Invalid length of Cisco control packet (%d bytes)\n",
				    skb->len);
			goto rx_error;
		}

		cisco_data = (struct cisco_packet*)(skb->data + sizeof
						    (struct hdlc_header));

		switch (ntohl (cisco_data->type)) {
		case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
			rcu_read_lock();
			in_dev = __in_dev_get_rcu(dev);
			addr = 0;
			mask = ~cpu_to_be32(0); /* is the mask correct? */

			if (in_dev != NULL) {
				struct in_ifaddr **ifap = &in_dev->ifa_list;

				while (*ifap != NULL) {
					if (strcmp(dev->name,
						   (*ifap)->ifa_label) == 0) {
						addr = (*ifap)->ifa_local;
						mask = (*ifap)->ifa_mask;
						break;
					}
					ifap = &(*ifap)->ifa_next;
				}

				cisco_keepalive_send(dev, CISCO_ADDR_REPLY,
						     addr, mask);
			}
			rcu_read_unlock();
			dev_kfree_skb_any(skb);
			return NET_RX_SUCCESS;

		case CISCO_ADDR_REPLY:
			netdev_info(dev, "Unexpected Cisco IP address reply\n");
			goto rx_error;

		case CISCO_KEEPALIVE_REQ:
			spin_lock(&st->lock);
			st->rxseq = ntohl(cisco_data->par1);
			ack = ntohl(cisco_data->par2);
			if (ack && (ack == st->txseq ||
				    /* our current REQ may be in transit */
				    ack == st->txseq - 1)) {
				st->last_poll = jiffies;
				if (!st->up) {
					u32 sec, min, hrs, days;
					sec = ntohl(cisco_data->time) / 1000;
					min = sec / 60; sec -= min * 60;
					hrs = min / 60; min -= hrs * 60;
					days = hrs / 24; hrs -= days * 24;
					netdev_info(dev, "Link up (peer uptime %ud%uh%um%us)\n",
						    days, hrs, min, sec);
					netif_dormant_off(dev);
					st->up = 1;
				}
			}
			spin_unlock(&st->lock);

			dev_kfree_skb_any(skb);
			return NET_RX_SUCCESS;
		} /* switch (keepalive type) */
	} /* switch (protocol) */

	netdev_info(dev, "Unsupported protocol %x\n", ntohs(data->protocol));
	dev_kfree_skb_any(skb);
	return NET_RX_DROP;

rx_error:
	dev->stats.rx_errors++; /* Mark error */
	dev_kfree_skb_any(skb);
	return NET_RX_DROP;
}
Ejemplo n.º 10
0
/* SCA: RCR+ must supply id, len and data
   SCN: RCR- must supply code, id, len and data
   STA: RTR must supply id
   SCJ: RUC must supply CP packet len and data */
static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code,
			 u8 id, unsigned int len, const void *data)
{
	int old_state, action;
	struct ppp *ppp = get_ppp(dev);
	struct proto *proto = get_proto(dev, pid);

	old_state = proto->state;
	BUG_ON(old_state >= STATES);
	BUG_ON(event >= EVENTS);

#if DEBUG_STATE
	printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) %s ...\n", dev->name,
	       proto_name(pid), event_names[event], state_names[proto->state]);
#endif

	action = cp_table[event][old_state];

	proto->state = action & STATE_MASK;
	if (action & (SCR | STR)) /* set Configure-Req/Terminate-Req timer */
		mod_timer(&proto->timer, proto->timeout =
			  jiffies + ppp->req_timeout * HZ);
	if (action & ZRC)
		proto->restart_counter = 0;
	if (action & IRC)
		proto->restart_counter = (proto->state == STOPPING) ?
			ppp->term_retries : ppp->cr_retries;

	if (action & SCR)	/* send Configure-Request */
		ppp_tx_cp(dev, pid, CP_CONF_REQ, proto->cr_id = ++ppp->seq,
			  0, NULL);
	if (action & SCA)	/* send Configure-Ack */
		ppp_tx_cp(dev, pid, CP_CONF_ACK, id, len, data);
	if (action & SCN)	/* send Configure-Nak/Reject */
		ppp_tx_cp(dev, pid, code, id, len, data);
	if (action & STR)	/* send Terminate-Request */
		ppp_tx_cp(dev, pid, CP_TERM_REQ, ++ppp->seq, 0, NULL);
	if (action & STA)	/* send Terminate-Ack */
		ppp_tx_cp(dev, pid, CP_TERM_ACK, id, 0, NULL);
	if (action & SCJ)	/* send Code-Reject */
		ppp_tx_cp(dev, pid, CP_CODE_REJ, ++ppp->seq, len, data);

	if (old_state != OPENED && proto->state == OPENED) {
		printk(KERN_INFO "%s: %s up\n", dev->name, proto_name(pid));
		if (pid == PID_LCP) {
			netif_dormant_off(dev);
			ppp_cp_event(dev, PID_IPCP, START, 0, 0, 0, NULL);
			ppp_cp_event(dev, PID_IPV6CP, START, 0, 0, 0, NULL);
			ppp->last_pong = jiffies;
			mod_timer(&proto->timer, proto->timeout =
				  jiffies + ppp->keepalive_interval * HZ);
		}
	}
	if (old_state == OPENED && proto->state != OPENED) {
		printk(KERN_INFO "%s: %s down\n", dev->name, proto_name(pid));
		if (pid == PID_LCP) {
			netif_dormant_on(dev);
			ppp_cp_event(dev, PID_IPCP, STOP, 0, 0, 0, NULL);
			ppp_cp_event(dev, PID_IPV6CP, STOP, 0, 0, 0, NULL);
		}
	}
	if (old_state != CLOSED && proto->state == CLOSED)
		del_timer(&proto->timer);

#if DEBUG_STATE
	printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) ... %s\n", dev->name,
	       proto_name(pid), event_names[event], state_names[proto->state]);
#endif
}
Ejemplo n.º 11
0
static int cisco_rx(struct sk_buff *skb)
{
	struct net_device *dev = skb->dev;
	hdlc_device *hdlc = dev_to_hdlc(dev);
	hdlc_header *data = (hdlc_header*)skb->data;
	cisco_packet *cisco_data;
	struct in_device *in_dev;
	u32 addr, mask;

	if (skb->len < sizeof(hdlc_header))
		goto rx_error;

	if (data->address != CISCO_MULTICAST &&
	    data->address != CISCO_UNICAST)
		goto rx_error;

	switch(ntohs(data->protocol)) {
	case CISCO_SYS_INFO:
		/* Packet is not needed, drop it. */
		dev_kfree_skb_any(skb);
		return NET_RX_SUCCESS;

	case CISCO_KEEPALIVE:
		if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN &&
		    skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) {
			printk(KERN_INFO "%s: Invalid length of Cisco "
			       "control packet (%d bytes)\n",
			       dev->name, skb->len);
			goto rx_error;
		}

		cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header));

		switch(ntohl (cisco_data->type)) {
		case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
			in_dev = dev->ip_ptr;
			addr = 0;
			mask = ~0; /* is the mask correct? */

			if (in_dev != NULL) {
				struct in_ifaddr **ifap = &in_dev->ifa_list;

				while (*ifap != NULL) {
					if (strcmp(dev->name,
						   (*ifap)->ifa_label) == 0) {
						addr = (*ifap)->ifa_local;
						mask = (*ifap)->ifa_mask;
						break;
					}
					ifap = &(*ifap)->ifa_next;
				}

				cisco_keepalive_send(dev, CISCO_ADDR_REPLY,
						     addr, mask);
			}
			dev_kfree_skb_any(skb);
			return NET_RX_SUCCESS;

		case CISCO_ADDR_REPLY:
			printk(KERN_INFO "%s: Unexpected Cisco IP address "
			       "reply\n", dev->name);
			goto rx_error;

		case CISCO_KEEPALIVE_REQ:
			hdlc->state.cisco.rxseq = ntohl(cisco_data->par1);
			if (hdlc->state.cisco.request_sent &&
			    ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) {
				hdlc->state.cisco.last_poll = jiffies;
				if (!hdlc->state.cisco.up) {
					u32 sec, min, hrs, days;
					sec = ntohl(cisco_data->time) / 1000;
					min = sec / 60; sec -= min * 60;
					hrs = min / 60; min -= hrs * 60;
					days = hrs / 24; hrs -= days * 24;
					printk(KERN_INFO "%s: Link up (peer "
					       "uptime %ud%uh%um%us)\n",
					       dev->name, days, hrs,
					       min, sec);
					netif_dormant_off(dev);
					hdlc->state.cisco.up = 1;
				}
			}

			dev_kfree_skb_any(skb);
			return NET_RX_SUCCESS;
		} /* switch(keepalive type) */
	} /* switch(protocol) */

	printk(KERN_INFO "%s: Unsupported protocol %x\n", dev->name,
	       data->protocol);
	dev_kfree_skb_any(skb);
	return NET_RX_DROP;

 rx_error:
	hdlc->stats.rx_errors++; /* Mark error */
	dev_kfree_skb_any(skb);
	return NET_RX_DROP;
}