Release 4.7 net/tipc/subscr.c
/*
* net/tipc/subscr.c: TIPC network topology service
*
* Copyright (c) 2000-2006, Ericsson AB
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the names of the copyright holders nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* Alternatively, this software may be distributed under the terms of the
* GNU General Public License ("GPL") version 2 as published by the Free
* Software Foundation.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "core.h"
#include "name_table.h"
#include "subscr.h"
/**
* struct tipc_subscriber - TIPC network topology subscriber
* @kref: reference counter to tipc_subscription object
* @conid: connection identifier to server connecting to subscriber
* @lock: control access to subscriber
* @subscrp_list: list of subscription objects for this subscriber
*/
struct tipc_subscriber {
struct kref kref;
int conid;
spinlock_t lock;
struct list_head subscrp_list;
};
static void tipc_subscrp_delete(struct tipc_subscription *sub);
static void tipc_subscrb_put(struct tipc_subscriber *subscriber);
/**
* htohl - convert value to endianness used by destination
* @in: value to convert
* @swap: non-zero if endianness must be reversed
*
* Returns converted value
*/
static u32 htohl(u32 in, int swap)
{
return swap ? swab32(in) : in;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
neil horman | neil horman | 22 | 100.00% | 1 | 100.00% |
| Total | 22 | 100.00% | 1 | 100.00% |
static void tipc_subscrp_send_event(struct tipc_subscription *sub,
u32 found_lower, u32 found_upper,
u32 event, u32 port_ref, u32 node)
{
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
struct tipc_subscriber *subscriber = sub->subscriber;
struct kvec msg_sect;
msg_sect.iov_base = (void *)&sub->evt;
msg_sect.iov_len = sizeof(struct tipc_event);
sub->evt.event = htohl(event, sub->swap);
sub->evt.found_lower = htohl(found_lower, sub->swap);
sub->evt.found_upper = htohl(found_upper, sub->swap);
sub->evt.port.ref = htohl(port_ref, sub->swap);
sub->evt.port.node = htohl(node, sub->swap);
tipc_conn_sendmsg(tn->topsrv, subscriber->conid, NULL,
msg_sect.iov_base, msg_sect.iov_len);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 111 | 63.07% | 1 | 14.29% |
ying xue | ying xue | 35 | 19.89% | 3 | 42.86% |
neil horman | neil horman | 25 | 14.20% | 1 | 14.29% |
allan stephens | allan stephens | 4 | 2.27% | 1 | 14.29% |
paul gortmaker | paul gortmaker | 1 | 0.57% | 1 | 14.29% |
| Total | 176 | 100.00% | 7 | 100.00% |
/**
* tipc_subscrp_check_overlap - test for subscription overlap with the
* given values
*
* Returns 1 if there is overlap, otherwise 0.
*/
int tipc_subscrp_check_overlap(struct tipc_name_seq *seq, u32 found_lower,
u32 found_upper)
{
if (found_lower < seq->lower)
found_lower = seq->lower;
if (found_upper > seq->upper)
found_upper = seq->upper;
if (found_lower > found_upper)
return 0;
return 1;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 49 | 87.50% | 1 | 33.33% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 6 | 10.71% | 1 | 33.33% |
ying xue | ying xue | 1 | 1.79% | 1 | 33.33% |
| Total | 56 | 100.00% | 3 | 100.00% |
u32 tipc_subscrp_convert_seq_type(u32 type, int swap)
{
return htohl(type, swap);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 19 | 100.00% | 1 | 100.00% |
| Total | 19 | 100.00% | 1 | 100.00% |
void tipc_subscrp_convert_seq(struct tipc_name_seq *in, int swap,
struct tipc_name_seq *out)
{
out->type = htohl(in->type, swap);
out->lower = htohl(in->lower, swap);
out->upper = htohl(in->upper, swap);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 57 | 100.00% | 1 | 100.00% |
| Total | 57 | 100.00% | 1 | 100.00% |
void tipc_subscrp_report_overlap(struct tipc_subscription *sub, u32 found_lower,
u32 found_upper, u32 event, u32 port_ref,
u32 node, int must)
{
struct tipc_name_seq seq;
tipc_subscrp_convert_seq(&sub->evt.s.seq, sub->swap, &seq);
if (!tipc_subscrp_check_overlap(&seq, found_lower, found_upper))
return;
if (!must &&
!(htohl(sub->evt.s.filter, sub->swap) & TIPC_SUB_PORTS))
return;
tipc_subscrp_send_event(sub, found_lower, found_upper, event, port_ref,
node);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 64 | 60.38% | 1 | 16.67% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 36 | 33.96% | 2 | 33.33% |
ying xue | ying xue | 3 | 2.83% | 1 | 16.67% |
lijun chen | lijun chen | 2 | 1.89% | 1 | 16.67% |
paul gortmaker | paul gortmaker | 1 | 0.94% | 1 | 16.67% |
| Total | 106 | 100.00% | 6 | 100.00% |
static void tipc_subscrp_timeout(unsigned long data)
{
struct tipc_subscription *sub = (struct tipc_subscription *)data;
struct tipc_subscriber *subscriber = sub->subscriber;
/* Notify subscriber of timeout */
tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
TIPC_SUBSCR_TIMEOUT, 0, 0);
spin_lock_bh(&subscriber->lock);
tipc_subscrp_delete(sub);
spin_unlock_bh(&subscriber->lock);
tipc_subscrb_put(subscriber);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 48 | 53.93% | 1 | 12.50% |
ying xue | ying xue | 39 | 43.82% | 5 | 62.50% |
paul gortmaker | paul gortmaker | 1 | 1.12% | 1 | 12.50% |
allan stephens | allan stephens | 1 | 1.12% | 1 | 12.50% |
| Total | 89 | 100.00% | 8 | 100.00% |
static void tipc_subscrb_kref_release(struct kref *kref)
{
struct tipc_subscriber *subcriber = container_of(kref,
struct tipc_subscriber, kref);
kfree(subcriber);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 21 | 67.74% | 2 | 66.67% |
lijun chen | lijun chen | 10 | 32.26% | 1 | 33.33% |
| Total | 31 | 100.00% | 3 | 100.00% |
static void tipc_subscrb_put(struct tipc_subscriber *subscriber)
{
kref_put(&subscriber->kref, tipc_subscrb_kref_release);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 16 | 76.19% | 1 | 50.00% |
lijun chen | lijun chen | 5 | 23.81% | 1 | 50.00% |
| Total | 21 | 100.00% | 2 | 100.00% |
static void tipc_subscrb_get(struct tipc_subscriber *subscriber)
{
kref_get(&subscriber->kref);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 14 | 73.68% | 2 | 66.67% |
lijun chen | lijun chen | 5 | 26.32% | 1 | 33.33% |
| Total | 19 | 100.00% | 3 | 100.00% |
static struct tipc_subscriber *tipc_subscrb_create(int conid)
{
struct tipc_subscriber *subscriber;
subscriber = kzalloc(sizeof(*subscriber), GFP_ATOMIC);
if (!subscriber) {
pr_warn("Subscriber rejected, no memory\n");
return NULL;
}
kref_init(&subscriber->kref);
INIT_LIST_HEAD(&subscriber->subscrp_list);
subscriber->conid = conid;
spin_lock_init(&subscriber->lock);
return subscriber;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 77 | 100.00% | 2 | 100.00% |
| Total | 77 | 100.00% | 2 | 100.00% |
static void tipc_subscrb_delete(struct tipc_subscriber *subscriber)
{
struct tipc_subscription *sub, *temp;
u32 timeout;
spin_lock_bh(&subscriber->lock);
/* Destroy any existing subscriptions for subscriber */
list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list,
subscrp_list) {
timeout = htohl(sub->evt.s.timeout, sub->swap);
if ((timeout == TIPC_WAIT_FOREVER) || del_timer(&sub->timer)) {
tipc_subscrp_delete(sub);
tipc_subscrb_put(subscriber);
}
}
spin_unlock_bh(&subscriber->lock);
tipc_subscrb_put(subscriber);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 46 | 45.54% | 3 | 42.86% |
per liden | per liden | 27 | 26.73% | 1 | 14.29% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 26 | 25.74% | 1 | 14.29% |
paul gortmaker | paul gortmaker | 1 | 0.99% | 1 | 14.29% |
allan stephens | allan stephens | 1 | 0.99% | 1 | 14.29% |
| Total | 101 | 100.00% | 7 | 100.00% |
static void tipc_subscrp_delete(struct tipc_subscription *sub)
{
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
tipc_nametbl_unsubscribe(sub);
list_del(&sub->subscrp_list);
kfree(sub);
atomic_dec(&tn->subscription_count);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 38 | 74.51% | 3 | 75.00% |
per liden | per liden | 13 | 25.49% | 1 | 25.00% |
| Total | 51 | 100.00% | 4 | 100.00% |
static void tipc_subscrp_cancel(struct tipc_subscr *s,
struct tipc_subscriber *subscriber)
{
struct tipc_subscription *sub, *temp;
u32 timeout;
spin_lock_bh(&subscriber->lock);
/* Find first matching subscription, exit if not found */
list_for_each_entry_safe(sub, temp, &subscriber->subscrp_list,
subscrp_list) {
if (!memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr))) {
timeout = htohl(sub->evt.s.timeout, sub->swap);
if ((timeout == TIPC_WAIT_FOREVER) ||
del_timer(&sub->timer)) {
tipc_subscrp_delete(sub);
tipc_subscrb_put(subscriber);
}
break;
}
}
spin_unlock_bh(&subscriber->lock);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
lijun chen | lijun chen | 46 | 36.80% | 1 | 10.00% |
ying xue | ying xue | 33 | 26.40% | 4 | 40.00% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 26 | 20.80% | 1 | 10.00% |
jon paul maloy | jon paul maloy | 15 | 12.00% | 1 | 10.00% |
neil horman | neil horman | 3 | 2.40% | 1 | 10.00% |
paul gortmaker | paul gortmaker | 2 | 1.60% | 2 | 20.00% |
| Total | 125 | 100.00% | 10 | 100.00% |
static struct tipc_subscription *tipc_subscrp_create(struct net *net,
struct tipc_subscr *s,
int swap)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_subscription *sub;
u32 filter = htohl(s->filter, swap);
/* Refuse subscription if global limit exceeded */
if (atomic_read(&tn->subscription_count) >= TIPC_MAX_SUBSCRIPTIONS) {
pr_warn("Subscription rejected, limit reached (%u)\n",
TIPC_MAX_SUBSCRIPTIONS);
return NULL;
}
/* Allocate subscription object */
sub = kmalloc(sizeof(*sub), GFP_ATOMIC);
if (!sub) {
pr_warn("Subscription rejected, no memory\n");
return NULL;
}
/* Initialize subscription object */
sub->net = net;
if (((filter & TIPC_SUB_PORTS) && (filter & TIPC_SUB_SERVICE)) ||
(htohl(s->seq.lower, swap) > htohl(s->seq.upper, swap))) {
pr_warn("Subscription rejected, illegal request\n");
kfree(sub);
return NULL;
}
sub->swap = swap;
memcpy(&sub->evt.s, s, sizeof(*s));
atomic_inc(&tn->subscription_count);
return sub;
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 91 | 45.27% | 1 | 6.67% |
ying xue | ying xue | 30 | 14.93% | 4 | 26.67% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 29 | 14.43% | 4 | 26.67% |
allan stephens | allan stephens | 26 | 12.94% | 2 | 13.33% |
neil horman | neil horman | 20 | 9.95% | 2 | 13.33% |
erik hugne | erik hugne | 4 | 1.99% | 1 | 6.67% |
paul gortmaker | paul gortmaker | 1 | 0.50% | 1 | 6.67% |
| Total | 201 | 100.00% | 15 | 100.00% |
static void tipc_subscrp_subscribe(struct net *net, struct tipc_subscr *s,
struct tipc_subscriber *subscriber, int swap)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_subscription *sub = NULL;
u32 timeout;
sub = tipc_subscrp_create(net, s, swap);
if (!sub)
return tipc_conn_terminate(tn->topsrv, subscriber->conid);
spin_lock_bh(&subscriber->lock);
list_add(&sub->subscrp_list, &subscriber->subscrp_list);
tipc_subscrb_get(subscriber);
sub->subscriber = subscriber;
tipc_nametbl_subscribe(sub);
spin_unlock_bh(&subscriber->lock);
timeout = htohl(sub->evt.s.timeout, swap);
if (timeout == TIPC_WAIT_FOREVER)
return;
setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub);
mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout));
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 157 | 91.28% | 6 | 66.67% |
per liden | per liden | 10 | 5.81% | 1 | 11.11% |
ying xue | ying xue | 5 | 2.91% | 2 | 22.22% |
| Total | 172 | 100.00% | 9 | 100.00% |
/* Handle one termination request for the subscriber */
static void tipc_subscrb_release_cb(int conid, void *usr_data)
{
tipc_subscrb_delete((struct tipc_subscriber *)usr_data);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
per liden | per liden | 11 | 47.83% | 1 | 25.00% |
ying xue | ying xue | 11 | 47.83% | 2 | 50.00% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 1 | 4.35% | 1 | 25.00% |
| Total | 23 | 100.00% | 4 | 100.00% |
/* Handle one request to create a new subscription for the subscriber */
static void tipc_subscrb_rcv_cb(struct net *net, int conid,
struct sockaddr_tipc *addr, void *usr_data,
void *buf, size_t len)
{
struct tipc_subscriber *subscriber = usr_data;
struct tipc_subscr *s = (struct tipc_subscr *)buf;
int swap;
/* Determine subscriber's endianness */
swap = !(s->filter & (TIPC_SUB_PORTS | TIPC_SUB_SERVICE |
TIPC_SUB_CANCEL));
/* Detect & process a subscription cancellation request */
if (s->filter & htohl(TIPC_SUB_CANCEL, swap)) {
s->filter &= ~htohl(TIPC_SUB_CANCEL, swap);
return tipc_subscrp_cancel(s, subscriber);
}
tipc_subscrp_subscribe(net, s, subscriber, swap);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 80 | 68.38% | 4 | 44.44% |
ying xue | ying xue | 18 | 15.38% | 3 | 33.33% |
per liden | per liden | 18 | 15.38% | 1 | 11.11% |
erik hugne | erik hugne | 1 | 0.85% | 1 | 11.11% |
| Total | 117 | 100.00% | 9 | 100.00% |
/* Handle one request to establish a new subscriber */
static void *tipc_subscrb_connect_cb(int conid)
{
return (void *)tipc_subscrb_create(conid);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 14 | 70.00% | 3 | 60.00% |
per liden | per liden | 5 | 25.00% | 1 | 20.00% |
allan stephens | allan stephens | 1 | 5.00% | 1 | 20.00% |
| Total | 20 | 100.00% | 5 | 100.00% |
int tipc_topsrv_start(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
const char name[] = "topology_server";
struct tipc_server *topsrv;
struct sockaddr_tipc *saddr;
saddr = kzalloc(sizeof(*saddr), GFP_ATOMIC);
if (!saddr)
return -ENOMEM;
saddr->family = AF_TIPC;
saddr->addrtype = TIPC_ADDR_NAMESEQ;
saddr->addr.nameseq.type = TIPC_TOP_SRV;
saddr->addr.nameseq.lower = TIPC_TOP_SRV;
saddr->addr.nameseq.upper = TIPC_TOP_SRV;
saddr->scope = TIPC_NODE_SCOPE;
topsrv = kzalloc(sizeof(*topsrv), GFP_ATOMIC);
if (!topsrv) {
kfree(saddr);
return -ENOMEM;
}
topsrv->net = net;
topsrv->saddr = saddr;
topsrv->imp = TIPC_CRITICAL_IMPORTANCE;
topsrv->type = SOCK_SEQPACKET;
topsrv->max_rcvbuf_size = sizeof(struct tipc_subscr);
topsrv->tipc_conn_recvmsg = tipc_subscrb_rcv_cb;
topsrv->tipc_conn_new = tipc_subscrb_connect_cb;
topsrv->tipc_conn_release = tipc_subscrb_release_cb;
strncpy(topsrv->name, name, strlen(name) + 1);
tn->topsrv = topsrv;
atomic_set(&tn->subscription_count, 0);
return tipc_server_start(topsrv);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 216 | 94.74% | 3 | 50.00% |
per liden | per liden | 8 | 3.51% | 1 | 16.67% |
allan stephens | allan stephens | 2 | 0.88% | 1 | 16.67% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 2 | 0.88% | 1 | 16.67% |
| Total | 228 | 100.00% | 6 | 100.00% |
void tipc_topsrv_stop(struct net *net)
{
struct tipc_net *tn = net_generic(net, tipc_net_id);
struct tipc_server *topsrv = tn->topsrv;
tipc_server_stop(topsrv);
kfree(topsrv->saddr);
kfree(topsrv);
}
Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 39 | 81.25% | 3 | 75.00% |
per liden | per liden | 9 | 18.75% | 1 | 25.00% |
| Total | 48 | 100.00% | 4 | 100.00% |
Overall Contributors
| Person | Tokens | Prop | Commits | CommitProp |
ying xue | ying xue | 689 | 37.98% | 9 | 27.27% |
per liden | per liden | 482 | 26.57% | 1 | 3.03% |
parthasarathy bhuvaragan | parthasarathy bhuvaragan | 439 | 24.20% | 10 | 30.30% |
neil horman | neil horman | 71 | 3.91% | 2 | 6.06% |
lijun chen | lijun chen | 68 | 3.75% | 1 | 3.03% |
allan stephens | allan stephens | 37 | 2.04% | 5 | 15.15% |
jon paul maloy | jon paul maloy | 15 | 0.83% | 1 | 3.03% |
paul gortmaker | paul gortmaker | 8 | 0.44% | 2 | 6.06% |
erik hugne | erik hugne | 5 | 0.28% | 2 | 6.06% |
| Total | 1814 | 100.00% | 33 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.