Exemplo n.º 1
0
static void iscsi_sw_tcp_conn_set_callbacks(struct iscsi_conn *conn)
{
	struct iscsi_tcp_conn *tcp_conn = conn->dd_data;
	struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data;
	struct sock *sk = tcp_sw_conn->sock->sk;

	/* assign new callbacks */
	write_lock_bh(&sk->sk_callback_lock);
	sk->sk_user_data = conn;
	tcp_sw_conn->old_data_ready = sk->sk_data_ready;
	tcp_sw_conn->old_state_change = sk->sk_state_change;
	tcp_sw_conn->old_write_space = sk->sk_write_space;
	sk->sk_data_ready = iscsi_sw_tcp_data_ready;
	sk->sk_state_change = iscsi_sw_tcp_state_change;
	sk->sk_write_space = iscsi_sw_tcp_write_space;
	write_unlock_bh(&sk->sk_callback_lock);
}
Exemplo n.º 2
0
/*
 * removal a call's user ID from the socket tree to make the user ID available
 * again and so that it won't be seen again in association with that call
 */
void rxrpc_remove_user_ID(struct rxrpc_sock *rx, struct rxrpc_call *call)
{
	_debug("RELEASE CALL %d", call->debug_id);

	if (test_bit(RXRPC_CALL_HAS_USERID, &call->flags)) {
		write_lock_bh(&rx->call_lock);
		rb_erase(&call->sock_node, &call->socket->calls);
		clear_bit(RXRPC_CALL_HAS_USERID, &call->flags);
		write_unlock_bh(&rx->call_lock);
	}

	read_lock_bh(&call->state_lock);
	if (!test_bit(RXRPC_CALL_RELEASED, &call->flags) &&
	    !test_and_set_bit(RXRPC_CALL_RELEASE, &call->events))
		rxrpc_queue_call(call);
	read_unlock_bh(&call->state_lock);
}
Exemplo n.º 3
0
static void
ip6_tnl_dev_uninit(struct net_device *dev)
{
	struct ip6_tnl *t = netdev_priv(dev);
	struct net *net = dev_net(dev);
	struct ip6_tnl_net *ip6n = net_generic(net, ip6_tnl_net_id);

	if (dev == ip6n->fb_tnl_dev) {
		write_lock_bh(&ip6_tnl_lock);
		ip6n->tnls_wc[0] = NULL;
		write_unlock_bh(&ip6_tnl_lock);
	} else {
		ip6_tnl_unlink(ip6n, t);
	}
	ip6_tnl_dst_reset(t);
	dev_put(dev);
}
Exemplo n.º 4
0
void dp_bfd_timer_send_callback(unsigned long mydis)
{    
    dp_bfd_session_s *session;
   
    session = dp_bfd_find_session_simple(mydis);
    if(NULL == session)
    {
        if(dp_bfd_debug & DEBUG_BFD_TIMER)
            printk("dp_bfd_timer_send_callback session not found\n");
        return;
    }
    
    session->flag &= (~DP_BFD_SEND_TIMER_ON);
    if(session->bfd_cyc_switch)
    {
        session->bfd_cyc_handshake_time++;
        if(session->bfd_cyc_handshake_time >= BFD_CYC_HANDSHAKE_TIMEOUT)
        {
            session->bfd_cyc_switch = 0;
            session->fail = 1;
            dp_bfd_send_event(session, EVENT_BFD_CYC_HANDSHAKE_TIMEOUT, BFD_EVENT_CRUCIAL);
        }
    }
        
    if(!(session->flag & DP_BFD_SEND_TIMER_ON))
    {
        session->send_timer.expires = jiffies + session->send_interval;
        session->send_timer.data = mydis;
        session->send_timer.function = dp_bfd_timer_send_callback;
        add_timer_on(&session->send_timer, 1);
        session->flag |= DP_BFD_SEND_TIMER_ON;
        
        if(dp_bfd_debug & DEBUG_BFD_TIMER)
            printk("dp_bfd_timer_send_callback add send_timer\n");
    }
    else
    {
        mod_timer(&session->send_timer, jiffies + session->send_interval);
        
        if(dp_bfd_debug & DEBUG_BFD_TIMER)
            printk("dp_bfd_timer_send_callback mod send_timer\n");
    }

    dp_bfd_send_msg(session, DP_BFD_SEND_CONTROL_PACKET);
    write_unlock_bh(&g_session_cask[session->packet.my_discriminator%256].session_lock);
}
Exemplo n.º 5
0
struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev)
{	
	struct rt6_info *rt;
	struct fib6_node *fn;

	fn = &ip6_routing_table;

	write_lock_bh(&rt6_lock);
	for (rt = fn->leaf; rt; rt=rt->u.next) {
		if (dev == rt->rt6i_dev &&
		    ipv6_addr_cmp(&rt->rt6i_gateway, addr) == 0)
			break;
	}
	if (rt)
		dst_hold(&rt->u.dst);
	write_unlock_bh(&rt6_lock);
	return rt;
}
Exemplo n.º 6
0
/*
 * abort a call, sending an ABORT packet to the peer
 */
static void rxrpc_send_abort(struct rxrpc_call *call, u32 abort_code)
{
	write_lock_bh(&call->state_lock);

	if (call->state <= RXRPC_CALL_COMPLETE) {
		call->state = RXRPC_CALL_LOCALLY_ABORTED;
		call->abort_code = abort_code;
		set_bit(RXRPC_CALL_ABORT, &call->events);
		del_timer_sync(&call->resend_timer);
		del_timer_sync(&call->ack_timer);
		clear_bit(RXRPC_CALL_RESEND_TIMER, &call->events);
		clear_bit(RXRPC_CALL_ACK, &call->events);
		clear_bit(RXRPC_CALL_RUN_RTIMER, &call->flags);
		rxrpc_queue_call(call);
	}

	write_unlock_bh(&call->state_lock);
}
Exemplo n.º 7
0
int tipc_net_start(u32 addr)
{
	char addr_string[16];

	write_lock_bh(&tipc_net_lock);
	tipc_own_addr = addr;
	tipc_named_reinit();
	tipc_port_reinit();
	tipc_bclink_init();
	write_unlock_bh(&tipc_net_lock);

	tipc_cfg_reinit();

	pr_info("Started in network mode\n");
	pr_info("Own node address %s, network identity %u\n",
		tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
	return 0;
}
Exemplo n.º 8
0
/* Handle the timer event */
static void aarp_expire_timeout(unsigned long unused)
{
	int ct;

	write_lock_bh(&aarp_lock);

	for (ct = 0; ct < AARP_HASH_SIZE; ct++) {
		__aarp_expire_timer(&resolved[ct]);
		__aarp_kick(&unresolved[ct]);
		__aarp_expire_timer(&unresolved[ct]);
		__aarp_expire_timer(&proxies[ct]);
	}

	write_unlock_bh(&aarp_lock);
	mod_timer(&aarp_timer, jiffies +
			       (unresolved_count ? sysctl_aarp_tick_time :
				sysctl_aarp_expiry_time));
}
Exemplo n.º 9
0
void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
{
	unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
	struct tcf_common **p1p;

	for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) {
		if (*p1p == p) {
			write_lock_bh(hinfo->lock);
			*p1p = p->tcfc_next;
			write_unlock_bh(hinfo->lock);
			gen_kill_estimator(&p->tcfc_bstats,
					   &p->tcfc_rate_est);
			kfree(p);
			return;
		}
	}
	WARN_ON(1);
}
Exemplo n.º 10
0
static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
{
	struct inet6_dev *ndev;

	ASSERT_RTNL();

	if (dev->mtu < IPV6_MIN_MTU)
		return NULL;

	ndev = kmalloc(sizeof(struct inet6_dev), GFP_KERNEL);

	if (ndev) {
		memset(ndev, 0, sizeof(struct inet6_dev));

		ndev->lock = RW_LOCK_UNLOCKED;
		ndev->dev = dev;
		memcpy(&ndev->cnf, &ipv6_devconf_dflt, sizeof(ndev->cnf));
		ndev->cnf.mtu6 = dev->mtu;
		ndev->cnf.sysctl = NULL;
		ndev->nd_parms = neigh_parms_alloc(dev, &nd_tbl);
		if (ndev->nd_parms == NULL) {
			kfree(ndev);
			return NULL;
		}
		inet6_dev_count++;
		/* We refer to the device */
		dev_hold(dev);

		write_lock_bh(&addrconf_lock);
		dev->ip6_ptr = ndev;
		/* One reference from device */
		in6_dev_hold(ndev);
		write_unlock_bh(&addrconf_lock);

		ipv6_mc_init_dev(ndev);

#ifdef CONFIG_SYSCTL
		neigh_sysctl_register(dev, ndev->nd_parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
		addrconf_sysctl_register(ndev, &ndev->cnf);
#endif
	}
	return ndev;
}
Exemplo n.º 11
0
int xfrm_unregister_type(struct xfrm_type *type, unsigned short family)
{
	struct xfrm_policy_afinfo *afinfo = xfrm_policy_get_afinfo(family);
	struct xfrm_type_map *typemap;
	int err = 0;

	if (unlikely(afinfo == NULL))
		return -EAFNOSUPPORT;
	typemap = afinfo->type_map;

	write_lock_bh(&typemap->lock);
	if (unlikely(typemap->map[type->proto] != type))
		err = -ENOENT;
	else
		typemap->map[type->proto] = NULL;
	write_unlock_bh(&typemap->lock);
	xfrm_policy_put_afinfo(afinfo);
	return err;
}
Exemplo n.º 12
0
struct l2t_entry *t3_l2t_get(struct t3cdev *cdev, struct neighbour *neigh,
			     struct net_device *dev)
{
	struct l2t_entry *e;
	struct l2t_data *d = L2DATA(cdev);
	u32 addr = *(u32 *) neigh->primary_key;
	int ifidx = neigh->dev->ifindex;
	int hash = arp_hash(addr, ifidx, d);
	struct port_info *p = netdev_priv(dev);
	int smt_idx = p->port_id;

	write_lock_bh(&d->lock);
	for (e = d->l2tab[hash].first; e; e = e->next)
		if (e->addr == addr && e->ifindex == ifidx &&
		    e->smt_idx == smt_idx) {
			l2t_hold(d, e);
			if (atomic_read(&e->refcnt) == 1)
				reuse_entry(e, neigh);
			goto done;
		}

	/* Need to allocate a new entry */
	e = alloc_l2e(d);
	if (e) {
		spin_lock(&e->lock);	/* avoid race with t3_l2t_free */
		e->next = d->l2tab[hash].first;
		d->l2tab[hash].first = e;
		e->state = L2T_STATE_RESOLVING;
		e->addr = addr;
		e->ifindex = ifidx;
		e->smt_idx = smt_idx;
		atomic_set(&e->refcnt, 1);
		neigh_replace(e, neigh);
		if (neigh->dev->priv_flags & IFF_802_1Q_VLAN)
			e->vlan = vlan_dev_vlan_id(neigh->dev);
		else
			e->vlan = VLAN_NONE;
		spin_unlock(&e->lock);
	}
done:
	write_unlock_bh(&d->lock);
	return e;
}
Exemplo n.º 13
0
static int arp_invalidate(struct net_device *dev, __be32 ip)
{
	struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
	int err = -ENXIO;
	struct neigh_table *tbl = &arp_tbl;

	if (neigh) {
		if (neigh->nud_state & ~NUD_NOARP)
			err = neigh_update(neigh, NULL, NUD_FAILED,
					   NEIGH_UPDATE_F_OVERRIDE|
					   NEIGH_UPDATE_F_ADMIN, 0);
		write_lock_bh(&tbl->lock);
		neigh_release(neigh);
		neigh_remove_one(neigh, tbl);
		write_unlock_bh(&tbl->lock);
	}

	return err;
}
Exemplo n.º 14
0
void dp_bfd_timer_echo_receive_callback(unsigned long mydis)
{
    dp_bfd_session_s *session;  
    
    session = dp_bfd_find_session_simple(mydis);
    if(NULL == session)
    {
        if(dp_bfd_debug & DEBUG_BFD_TIMER)
            printk("dp_bfd_timer_echo_receive_callback session not found\n");
        return;
    }
    
    session->flag &= (~DP_BFD_ECHORECV_TIMER_ON);
    session->packet.sta = DOWN;
    session->packet.diag = ECHO_FUNCTION_FAILED;
    
    if(session->flag & DP_BFD_ECHOSEND_TIMER_ON)
    {
        del_timer_sync(&session->echo_send_timer);
        session->flag &= (~DP_BFD_ECHOSEND_TIMER_ON);
    }
    
    if(session->flag & DP_BFD_SEND_TIMER_ON)
    {
        del_timer_sync(&session->send_timer);
        session->flag &= (~DP_BFD_SEND_TIMER_ON);
    }
    if(session->flag & DP_BFD_RECEIVE_TIMER_ON)
    {
        del_timer_sync(&session->receive_timer);
        session->flag &= (~DP_BFD_RECEIVE_TIMER_ON);
    }
    
    dp_bfd_send_msg(session, DP_BFD_SEND_CONTROL_PACKET);
    
    session->packet.your_discriminator = 0;
    if(DP_BFD_INITIATIVE_MODE == session->session_mode)
    {
        dp_bfd_timer_cyc_handshake_add(session);
    }
    
    write_unlock_bh(&g_session_cask[session->packet.my_discriminator%256].session_lock);
}
void ip_mc_inc_group(struct in_device *in_dev, u32 addr)
{
    struct ip_mc_list *im;

    ASSERT_RTNL();

    for (im=in_dev->mc_list; im; im=im->next) {
        if (im->multiaddr == addr) {
            im->users++;
            goto out;
        }
    }

    im = (struct ip_mc_list *)kmalloc(sizeof(*im), GFP_KERNEL);
    if (!im)
        goto out;

    im->users=1;
    im->interface=in_dev;
    in_dev_hold(in_dev);
    im->multiaddr=addr;
    atomic_set(&im->refcnt, 1);
    spin_lock_init(&im->lock);
#ifdef  CONFIG_IP_MULTICAST
    im->tm_running=0;
    init_timer(&im->timer);
    im->timer.data=(unsigned long)im;
    im->timer.function=&igmp_timer_expire;
    im->unsolicit_count = IGMP_Unsolicited_Report_Count;
    im->reporter = 0;
#endif
    im->loaded = 0;
    write_lock_bh(&in_dev->lock);
    im->next=in_dev->mc_list;
    in_dev->mc_list=im;
    write_unlock_bh(&in_dev->lock);
    igmp_group_added(im);
    if (in_dev->dev->flags & IFF_UP)
        ip_rt_multicast_event(in_dev);
out:
    return;
}
Exemplo n.º 16
0
void tipc_ref_discard(u32 ref)
{
	struct reference *entry;
	u32 index;
	u32 index_mask;

	if (!tipc_ref_table.entries) {
		err("Reference table not found during discard attempt\n");
		return;
	}

	index_mask = tipc_ref_table.index_mask;
	index = ref & index_mask;
	entry = &(tipc_ref_table.entries[index]);

	write_lock_bh(&ref_table_lock);

	if (!entry->object) {
		err("Attempt to discard reference to non-existent object\n");
		goto exit;
	}
	if (entry->ref != ref) {
		err("Attempt to discard non-existent reference\n");
		goto exit;
	}

	

	entry->object = NULL;
	entry->ref = (ref & ~index_mask) + (index_mask + 1);

	

	if (tipc_ref_table.first_free == 0)
		tipc_ref_table.first_free = index;
	else
		tipc_ref_table.entries[tipc_ref_table.last_free].ref |= index;
	tipc_ref_table.last_free = index;

exit:
	write_unlock_bh(&ref_table_lock);
}
Exemplo n.º 17
0
static int ip6mr_mfc_delete(struct mf6cctl *mfc)
{
	int line;
	struct mfc6_cache *c, **cp;

	line = MFC6_HASH(&mfc->mf6cc_mcastgrp.sin6_addr, &mfc->mf6cc_origin.sin6_addr);

	for (cp = &mfc6_cache_array[line]; (c = *cp) != NULL; cp = &c->next) {
		if (ipv6_addr_equal(&c->mf6c_origin, &mfc->mf6cc_origin.sin6_addr) &&
		    ipv6_addr_equal(&c->mf6c_mcastgrp, &mfc->mf6cc_mcastgrp.sin6_addr)) {
			write_lock_bh(&mrt_lock);
			*cp = c->next;
			write_unlock_bh(&mrt_lock);

			kmem_cache_free(mrt_cachep, c);
			return 0;
		}
	}
	return -ENOENT;
}
Exemplo n.º 18
0
static void add_free_chan(struct pppox_sock *po)
{
	static __u16 call_id=0;
	struct pppox_sock *p;

	write_lock_bh(&chan_lock);
	while (1) {
		if (++call_id==0) continue;
		for(p=chans[HASH(call_id)]; p; p=p->next)
			if (p->proto.pptp.src_addr.call_id==call_id)
				break;
		if (!p){
			po->proto.pptp.src_addr.call_id=call_id;
			po->next=chans[HASH(call_id)];
			chans[HASH(call_id)]=po;
			break;
		}
	}
	write_unlock_bh(&chan_lock);
}
Exemplo n.º 19
0
static unsigned int
spd_proc_poll(
        struct file *file,
        struct poll_table_struct *table)
{
    unsigned int mask = 0;

    poll_wait(file, &wait_queue, table);

    write_lock_bh(&spd_proc_lock);

    if (bypass_packet_set == true)
    {
        mask |= (POLLIN | POLLRDNORM);
    }

    write_unlock_bh(&spd_proc_lock);

    return mask;
}
Exemplo n.º 20
0
void tcf_hash_destroy(struct tcf_common *p, struct tcf_hashinfo *hinfo)
{
	unsigned int h = tcf_hash(p->tcfc_index, hinfo->hmask);
	struct tcf_common **p1p;

	for (p1p = &hinfo->htab[h]; *p1p; p1p = &(*p1p)->tcfc_next) {
		if (*p1p == p) {
			write_lock_bh(hinfo->lock);
			*p1p = p->tcfc_next;
			write_unlock_bh(hinfo->lock);
#ifdef CONFIG_NET_ESTIMATOR
			gen_kill_estimator(&p->tcfc_bstats,
					   &p->tcfc_rate_est);
#endif
			kfree(p);
			return;
		}
	}
	BUG_TRAP(0);
}
Exemplo n.º 21
0
/*
 * Caller must hold a reference to intrfc
 */
int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
		     unsigned char *node)
{
	struct ipx_route *rt;
	int rc;

	/* Get a route structure; either existing or create */
	rt = ipxrtr_lookup(network);
	if (!rt) {
		rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
		rc = -EAGAIN;
		if (!rt)
			goto out;

		atomic_set(&rt->refcnt, 1);
		ipxrtr_hold(rt);
		write_lock_bh(&ipx_routes_lock);
		list_add(&rt->node, &ipx_routes);
		write_unlock_bh(&ipx_routes_lock);
	} else {
		rc = -EEXIST;
		if (intrfc == ipx_internal_net)
			goto out_put;
	}

	rt->ir_net 	= network;
	rt->ir_intrfc 	= intrfc;
	if (!node) {
		memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
		rt->ir_routed = 0;
	} else {
		memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
		rt->ir_routed = 1;
	}

	rc = 0;
out_put:
	ipxrtr_put(rt);
out:
	return rc;
}
Exemplo n.º 22
0
struct in_device *inetdev_init(struct net_device *dev)
{
	struct in_device *in_dev;

	ASSERT_RTNL();

	in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
	if (!in_dev)
		goto out;
	memset(in_dev, 0, sizeof(*in_dev));
	in_dev->lock = RW_LOCK_UNLOCKED;
	memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
	in_dev->cnf.sysctl = NULL;
	in_dev->dev = dev;
	if ((in_dev->arp_parms = neigh_parms_alloc(dev, &arp_tbl)) == NULL)
		goto out_kfree;
	inet_dev_count++;
	/* Reference in_dev->dev */
	dev_hold(dev);
#ifdef CONFIG_SYSCTL
	neigh_sysctl_register(dev, in_dev->arp_parms, NET_IPV4,
			      NET_IPV4_NEIGH, "ipv4", NULL);
#endif
	write_lock_bh(&inetdev_lock);
	dev->ip_ptr = in_dev;
	/* Account for reference dev->ip_ptr */
	in_dev_hold(in_dev);
	write_unlock_bh(&inetdev_lock);
#ifdef CONFIG_SYSCTL
	devinet_sysctl_register(in_dev, &in_dev->cnf);
#endif
	ip_mc_init_dev(in_dev);
	if (dev->flags & IFF_UP)
		ip_mc_up(in_dev);
out:
	return in_dev;
out_kfree:
	kfree(in_dev);
	in_dev = NULL;
	goto out;
}
Exemplo n.º 23
0
/* ----- Proc fs support ------ */
static int sco_sock_dump(char *buf, struct bluez_sock_list *list)
{
	struct sco_pinfo *pi;
	struct sock *sk;
	char *ptr = buf;

	write_lock_bh(&list->lock);

	for (sk = list->head; sk; sk = sk->next) {
		pi = sco_pi(sk);
		ptr += sprintf(ptr, "%s %s %d\n",
				batostr(&bluez_pi(sk)->src), batostr(&bluez_pi(sk)->dst),
				sk->state); 
	}

	write_unlock_bh(&list->lock);

	ptr += sprintf(ptr, "\n");

	return ptr - buf;
}
void nf_conntrack_l4proto_unregister(struct nf_conntrack_l4proto *l4proto)
{
	BUG_ON(l4proto->l3proto >= PF_MAX);

	if (l4proto == &nf_conntrack_l4proto_generic) {
		nf_ct_l4proto_unregister_sysctl(l4proto);
		return;
	}

	write_lock_bh(&nf_conntrack_lock);
	BUG_ON(nf_ct_protos[l4proto->l3proto][l4proto->l4proto] != l4proto);
	rcu_assign_pointer(nf_ct_protos[l4proto->l3proto][l4proto->l4proto],
			   &nf_conntrack_l4proto_generic);
	write_unlock_bh(&nf_conntrack_lock);
	synchronize_rcu();

	nf_ct_l4proto_unregister_sysctl(l4proto);

	/* Remove all contrack entries for this protocol */
	nf_ct_iterate_cleanup(kill_l4proto, l4proto);
}
Exemplo n.º 25
0
static void fl_release(struct ip6_flowlabel *fl)
{
	write_lock_bh(&ip6_fl_lock);

	fl->lastuse = jiffies;
	if (atomic_dec_and_test(&fl->users)) {
		unsigned long ttd = fl->lastuse + fl->linger;
		if (time_after(ttd, fl->expires))
			fl->expires = ttd;
		ttd = fl->expires;
		if (fl->opt && fl->share == IPV6_FL_S_EXCL) {
			struct ipv6_txoptions *opt = fl->opt;
			fl->opt = NULL;
			kfree(opt);
		}
		if (!timer_pending(&ip6_fl_gc_timer) ||
		    time_after(ip6_fl_gc_timer.expires, ttd))
			mod_timer(&ip6_fl_gc_timer, ttd);
	}
	write_unlock_bh(&ip6_fl_lock);
}
Exemplo n.º 26
0
/**
 *	llc_sap_open - open interface to the upper layers.
 *	@lsap: SAP number.
 *	@func: rcv func for datalink protos
 *
 *	Interface function to upper layer. Each one who wants to get a SAP
 *	(for example NetBEUI) should call this function. Returns the opened
 *	SAP for success, NULL for failure.
 */
struct llc_sap *llc_sap_open(unsigned char lsap,
			     int (*func)(struct sk_buff *skb,
					 struct net_device *dev,
					 struct packet_type *pt,
					 struct net_device *orig_dev))
{
	struct llc_sap *sap = NULL;

	write_lock_bh(&llc_sap_list_lock);
	if (__llc_sap_find(lsap)) /* SAP already exists */
		goto out;
	sap = llc_sap_alloc();
	if (!sap)
		goto out;
	sap->laddr.lsap = lsap;
	sap->rcv_func	= func;
	llc_add_sap(sap);
out:
	write_unlock_bh(&llc_sap_list_lock);
	return sap;
}
Exemplo n.º 27
0
/* Unregister connection and trigger lgr freeing if applicable
 */
static void smc_lgr_unregister_conn(struct smc_connection *conn)
{
	struct smc_link_group *lgr = conn->lgr;
	int reduced = 0;

	write_lock_bh(&lgr->conns_lock);
	if (conn->alert_token_local) {
		reduced = 1;
		__smc_lgr_unregister_conn(conn);
	}
	write_unlock_bh(&lgr->conns_lock);
	if (!reduced || lgr->conns_num)
		return;
	/* client link group creation always follows the server link group
	 * creation. For client use a somewhat higher removal delay time,
	 * otherwise there is a risk of out-of-sync link groups.
	 */
	mod_delayed_work(system_wq, &lgr->free_work,
			 lgr->role == SMC_CLNT ? SMC_LGR_FREE_DELAY_CLNT :
						 SMC_LGR_FREE_DELAY_SERV);
}
Exemplo n.º 28
0
void mipv6_shutdown_mn(void)
{
	struct mn_info *minfo, *tmp;
	DEBUG_FUNC();

	ipv6_ipv6_tunnel_unregister_hook(&mn_tunnel_rcv_send_bu_ops);

	ma_ctl_clean();

	unregister_netdevice_notifier(&mipv6_mn_dev_notifier);
	write_lock_bh(&mn_info_lock);
	for (minfo = mn_info_base; minfo;) {
		if (!minfo->is_at_home) 
			deprecate_addr(minfo);
		tmp = minfo;
		minfo = minfo->next;
		kfree(tmp);
		
	}
	write_unlock_bh(&mn_info_lock);
}
Exemplo n.º 29
0
static void netlink_table_grab(void)
{
	write_lock_bh(&nl_table_lock);

	if (atomic_read(&nl_table_users)) {
		DECLARE_WAITQUEUE(wait, current);

		add_wait_queue_exclusive(&nl_table_wait, &wait);
		for(;;) {
			set_current_state(TASK_UNINTERRUPTIBLE);
			if (atomic_read(&nl_table_users) == 0)
				break;
			write_unlock_bh(&nl_table_lock);
			schedule();
			write_lock_bh(&nl_table_lock);
		}

		__set_current_state(TASK_RUNNING);
		remove_wait_queue(&nl_table_wait, &wait);
	}
}
Exemplo n.º 30
0
static int ax25_rt_opt(struct ax25_route_opt_struct *rt_option)
{
	ax25_route *ax25_rt;
	ax25_dev *ax25_dev;
	int err = 0;

	if ((ax25_dev = ax25_addr_ax25dev(&rt_option->port_addr)) == NULL)
		return -EINVAL;

	write_lock_bh(&ax25_route_lock);

	ax25_rt = ax25_route_list;
	while (ax25_rt != NULL) {
		if (ax25_rt->dev == ax25_dev->dev &&
		    ax25cmp(&rt_option->dest_addr, &ax25_rt->callsign) == 0) {
			switch (rt_option->cmd) {
			case AX25_SET_RT_IPMODE:
				switch (rt_option->arg) {
				case ' ':
				case 'D':
				case 'V':
					ax25_rt->ip_mode = rt_option->arg;
					break;
				default:
					err = -EINVAL;
					goto out;
				}
				break;
			default:
				err = -EINVAL;
				goto out;
			}
		}
		ax25_rt = ax25_rt->next;
	}

out:
	write_unlock_bh(&ax25_route_lock);
	return err;
}