Release 4.11 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);
static void tipc_subscrp_put(struct tipc_subscription *subscription);
static void tipc_subscrp_get(struct tipc_subscription *subscription);
/**
* 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 | 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 | 111 | 63.07% | 1 | 14.29% |
Ying Xue | 35 | 19.89% | 3 | 42.86% |
Neil Horman | 25 | 14.20% | 1 | 14.29% |
Allan Stephens | 4 | 2.27% | 1 | 14.29% |
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 | 49 | 87.50% | 1 | 33.33% |
Parthasarathy Bhuvaragan | 6 | 10.71% | 1 | 33.33% |
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 | 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 | 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_get(sub);
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);
tipc_subscrp_put(sub);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Per Liden | 64 | 55.17% | 1 | 14.29% |
Parthasarathy Bhuvaragan | 46 | 39.66% | 3 | 42.86% |
Ying Xue | 3 | 2.59% | 1 | 14.29% |
Lijun Chen | 2 | 1.72% | 1 | 14.29% |
Paul Gortmaker | 1 | 0.86% | 1 | 14.29% |
Total | 116 | 100.00% | 7 | 100.00% |
static void tipc_subscrp_timeout(unsigned long data)
{
struct tipc_subscription *sub = (struct tipc_subscription *)data;
struct tipc_subscriber *subscriber = sub->subscriber;
spin_lock_bh(&subscriber->lock);
tipc_nametbl_unsubscribe(sub);
spin_unlock_bh(&subscriber->lock);
/* Notify subscriber of timeout */
tipc_subscrp_send_event(sub, sub->evt.s.seq.lower, sub->evt.s.seq.upper,
TIPC_SUBSCR_TIMEOUT, 0, 0);
tipc_subscrp_put(sub);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 45 | 50.56% | 3 | 42.86% |
Per Liden | 41 | 46.07% | 1 | 14.29% |
Allan Stephens | 1 | 1.12% | 1 | 14.29% |
Paul Gortmaker | 1 | 1.12% | 1 | 14.29% |
Parthasarathy Bhuvaragan | 1 | 1.12% | 1 | 14.29% |
Total | 89 | 100.00% | 7 | 100.00% |
static void tipc_subscrb_kref_release(struct kref *kref)
{
kfree(container_of(kref,struct tipc_subscriber, kref));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Ying Xue | 13 | 54.17% | 2 | 50.00% |
Lijun Chen | 9 | 37.50% | 1 | 25.00% |
Parthasarathy Bhuvaragan | 2 | 8.33% | 1 | 25.00% |
Total | 24 | 100.00% | 4 | 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 | 16 | 76.19% | 1 | 50.00% |
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 | 14 | 73.68% | 2 | 66.67% |
Lijun Chen | 5 | 26.32% | 1 | 33.33% |
Total | 19 | 100.00% | 3 | 100.00% |
static void tipc_subscrp_kref_release(struct kref *kref)
{
struct tipc_subscription *sub = container_of(kref,
struct tipc_subscription,
kref);
struct tipc_net *tn = net_generic(sub->net, tipc_net_id);
struct tipc_subscriber *subscriber = sub->subscriber;
spin_lock_bh(&subscriber->lock);
list_del(&sub->subscrp_list);
atomic_dec(&tn->subscription_count);
spin_unlock_bh(&subscriber->lock);
kfree(sub);
tipc_subscrb_put(subscriber);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 63 | 69.23% | 1 | 33.33% |
Ying Xue | 28 | 30.77% | 2 | 66.67% |
Total | 91 | 100.00% | 3 | 100.00% |
static void tipc_subscrp_put(struct tipc_subscription *subscription)
{
kref_put(&subscription->kref, tipc_subscrp_kref_release);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 19 | 90.48% | 1 | 50.00% |
Ying Xue | 2 | 9.52% | 1 | 50.00% |
Total | 21 | 100.00% | 2 | 100.00% |
static void tipc_subscrp_get(struct tipc_subscription *subscription)
{
kref_get(&subscription->kref);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 13 | 68.42% | 1 | 50.00% |
Ying Xue | 6 | 31.58% | 1 | 50.00% |
Total | 19 | 100.00% | 2 | 100.00% |
/* tipc_subscrb_subscrp_delete - delete a specific subscription or all
* subscriptions for a given subscriber.
*/
static void tipc_subscrb_subscrp_delete(struct tipc_subscriber *subscriber,
struct tipc_subscr *s)
{
struct list_head *subscription_list = &subscriber->subscrp_list;
struct tipc_subscription *sub, *temp;
spin_lock_bh(&subscriber->lock);
list_for_each_entry_safe(sub, temp, subscription_list, subscrp_list) {
if (s && memcmp(s, &sub->evt.s, sizeof(struct tipc_subscr)))
continue;
tipc_nametbl_unsubscribe(sub);
tipc_subscrp_get(sub);
spin_unlock_bh(&subscriber->lock);
tipc_subscrp_delete(sub);
tipc_subscrp_put(sub);
spin_lock_bh(&subscriber->lock);
if (s)
break;
}
spin_unlock_bh(&subscriber->lock);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 62 | 49.21% | 2 | 22.22% |
Ying Xue | 40 | 31.75% | 4 | 44.44% |
Per Liden | 22 | 17.46% | 1 | 11.11% |
Allan Stephens | 1 | 0.79% | 1 | 11.11% |
Paul Gortmaker | 1 | 0.79% | 1 | 11.11% |
Total | 126 | 100.00% | 9 | 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;
}
INIT_LIST_HEAD(&subscriber->subscrp_list);
kref_init(&subscriber->kref);
subscriber->conid = conid;
spin_lock_init(&subscriber->lock);
return subscriber;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 49 | 63.64% | 1 | 33.33% |
Ying Xue | 16 | 20.78% | 1 | 33.33% |
Per Liden | 12 | 15.58% | 1 | 33.33% |
Total | 77 | 100.00% | 3 | 100.00% |
static void tipc_subscrb_delete(struct tipc_subscriber *subscriber)
{
tipc_subscrb_subscrp_delete(subscriber, NULL);
tipc_subscrb_put(subscriber);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Lijun Chen | 10 | 43.48% | 1 | 25.00% |
Parthasarathy Bhuvaragan | 8 | 34.78% | 1 | 25.00% |
Ying Xue | 4 | 17.39% | 1 | 25.00% |
Paul Gortmaker | 1 | 4.35% | 1 | 25.00% |
Total | 23 | 100.00% | 4 | 100.00% |
static void tipc_subscrp_delete(struct tipc_subscription *sub)
{
u32 timeout = htohl(sub->evt.s.timeout, sub->swap);
if (timeout == TIPC_WAIT_FOREVER || del_timer(&sub->timer))
tipc_subscrp_put(sub);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 31 | 64.58% | 2 | 33.33% |
Lijun Chen | 10 | 20.83% | 1 | 16.67% |
Ying Xue | 6 | 12.50% | 2 | 33.33% |
Jon Paul Maloy | 1 | 2.08% | 1 | 16.67% |
Total | 48 | 100.00% | 6 | 100.00% |
static void tipc_subscrp_cancel(struct tipc_subscr *s,
struct tipc_subscriber *subscriber)
{
tipc_subscrb_subscrp_delete(subscriber, s);
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 18 | 78.26% | 1 | 33.33% |
Ying Xue | 4 | 17.39% | 1 | 33.33% |
Lijun Chen | 1 | 4.35% | 1 | 33.33% |
Total | 23 | 100.00% | 3 | 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);
kref_init(&sub->kref);
return sub;
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Per Liden | 91 | 43.54% | 1 | 6.25% |
Parthasarathy Bhuvaragan | 37 | 17.70% | 5 | 31.25% |
Ying Xue | 30 | 14.35% | 4 | 25.00% |
Allan Stephens | 26 | 12.44% | 2 | 12.50% |
Neil Horman | 20 | 9.57% | 2 | 12.50% |
Erik Hugne | 4 | 1.91% | 1 | 6.25% |
Paul Gortmaker | 1 | 0.48% | 1 | 6.25% |
Total | 209 | 100.00% | 16 | 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);
sub->subscriber = subscriber;
tipc_nametbl_subscribe(sub);
tipc_subscrb_get(subscriber);
spin_unlock_bh(&subscriber->lock);
setup_timer(&sub->timer, tipc_subscrp_timeout, (unsigned long)sub);
timeout = htohl(sub->evt.s.timeout, swap);
if (timeout != TIPC_WAIT_FOREVER)
mod_timer(&sub->timer, jiffies + msecs_to_jiffies(timeout));
}
Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 156 | 91.23% | 6 | 66.67% |
Per Liden | 10 | 5.85% | 1 | 11.11% |
Ying Xue | 5 | 2.92% | 2 | 22.22% |
Total | 171 | 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 | 11 | 47.83% | 1 | 25.00% |
Ying Xue | 11 | 47.83% | 2 | 50.00% |
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 | 80 | 68.38% | 4 | 44.44% |
Per Liden | 18 | 15.38% | 1 | 11.11% |
Ying Xue | 18 | 15.38% | 3 | 33.33% |
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 | 14 | 70.00% | 3 | 60.00% |
Per Liden | 5 | 25.00% | 1 | 20.00% |
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 | 216 | 94.74% | 3 | 50.00% |
Per Liden | 8 | 3.51% | 1 | 16.67% |
Allan Stephens | 2 | 0.88% | 1 | 16.67% |
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 | 39 | 81.25% | 3 | 75.00% |
Per Liden | 9 | 18.75% | 1 | 25.00% |
Total | 48 | 100.00% | 4 | 100.00% |
Overall Contributors
Person | Tokens | Prop | Commits | CommitProp |
Parthasarathy Bhuvaragan | 691 | 36.01% | 10 | 29.41% |
Ying Xue | 599 | 31.21% | 10 | 29.41% |
Per Liden | 469 | 24.44% | 1 | 2.94% |
Neil Horman | 68 | 3.54% | 2 | 5.88% |
Lijun Chen | 42 | 2.19% | 1 | 2.94% |
Allan Stephens | 37 | 1.93% | 5 | 14.71% |
Paul Gortmaker | 7 | 0.36% | 2 | 5.88% |
Erik Hugne | 5 | 0.26% | 2 | 5.88% |
Jon Paul Maloy | 1 | 0.05% | 1 | 2.94% |
Total | 1919 | 100.00% | 34 | 100.00% |
Information contained on this website is for historical information purposes only and does not indicate or represent copyright ownership.