Commit b7d5e297 authored by David S. Miller's avatar David S. Miller

Merge branch 'tipc-cleanups-and-simplifications'

Jon Maloy says:

====================
tipc: cleanups and simplifications

We do a number of cleanups and simplifications, especially regarding
call signatures in the binding table. This makes the code easier to
understand and serves as preparation for upcoming functional additions.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 5c9e418b 5c834950
......@@ -3,6 +3,7 @@
*
* Copyright (c) 2000-2006, 2018, Ericsson AB
* Copyright (c) 2004-2005, 2010-2011, Wind River Systems
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......
......@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2006, 2018, Ericsson AB
* Copyright (c) 2004-2005, Wind River Systems
* Copyright (c) 2020, Red Hat Inc
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -44,6 +44,50 @@
#include <net/netns/generic.h>
#include "core.h"
/* Struct tipc_uaddr: internal version of struct sockaddr_tipc.
* Must be kept aligned both regarding field positions and size.
*/
struct tipc_uaddr {
unsigned short family;
unsigned char addrtype;
signed char scope;
union {
struct {
struct tipc_service_addr sa;
u32 lookup_node;
};
struct tipc_service_range sr;
struct tipc_socket_addr sk;
};
};
static inline void tipc_uaddr(struct tipc_uaddr *ua, u32 atype, u32 scope,
u32 type, u32 lower, u32 upper)
{
ua->family = AF_TIPC;
ua->addrtype = atype;
ua->scope = scope;
ua->sr.type = type;
ua->sr.lower = lower;
ua->sr.upper = upper;
}
static inline bool tipc_uaddr_valid(struct tipc_uaddr *ua, int len)
{
u32 atype;
if (len < sizeof(struct sockaddr_tipc))
return false;
atype = ua->addrtype;
if (ua->family != AF_TIPC)
return false;
if (atype == TIPC_SERVICE_ADDR || atype == TIPC_SOCKET_ADDR)
return true;
if (atype == TIPC_SERVICE_RANGE)
return ua->sr.upper >= ua->sr.lower;
return false;
}
static inline u32 tipc_own_addr(struct net *net)
{
return tipc_net(net)->node_addr;
......
......@@ -707,8 +707,11 @@ bool tipc_msg_skb_clone(struct sk_buff_head *msg, struct sk_buff_head *cpy)
bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
{
struct tipc_msg *msg = buf_msg(skb);
u32 dport, dnode;
u32 onode = tipc_own_addr(net);
u32 scope = msg_lookup_scope(msg);
u32 self = tipc_own_addr(net);
u32 inst = msg_nameinst(msg);
struct tipc_socket_addr sk;
struct tipc_uaddr ua;
if (!msg_isdata(msg))
return false;
......@@ -722,16 +725,16 @@ bool tipc_msg_lookup_dest(struct net *net, struct sk_buff *skb, int *err)
msg = buf_msg(skb);
if (msg_reroute_cnt(msg))
return false;
dnode = tipc_scope2node(net, msg_lookup_scope(msg));
dport = tipc_nametbl_translate(net, msg_nametype(msg),
msg_nameinst(msg), &dnode);
if (!dport)
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, scope,
msg_nametype(msg), inst, inst);
sk.node = tipc_scope2node(net, scope);
if (!tipc_nametbl_lookup_anycast(net, &ua, &sk))
return false;
msg_incr_reroute_cnt(msg);
if (dnode != onode)
msg_set_prevnode(msg, onode);
msg_set_destnode(msg, dnode);
msg_set_destport(msg, dport);
if (sk.node != self)
msg_set_prevnode(msg, self);
msg_set_destnode(msg, sk.node);
msg_set_destport(msg, sk.ref);
*err = TIPC_OK;
return true;
......
/*
* net/tipc/name_distr.c: TIPC name distribution code
*
* Copyright (c) 2000-2006, 2014, Ericsson AB
* Copyright (c) 2000-2006, 2014-2019, Ericsson AB
* Copyright (c) 2005, 2010-2011, Wind River Systems
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -55,10 +56,10 @@ struct distr_queue_item {
*/
static void publ_to_item(struct distr_item *i, struct publication *p)
{
i->type = htonl(p->type);
i->lower = htonl(p->lower);
i->upper = htonl(p->upper);
i->port = htonl(p->port);
i->type = htonl(p->sr.type);
i->lower = htonl(p->sr.lower);
i->upper = htonl(p->sr.upper);
i->port = htonl(p->sk.ref);
i->key = htonl(p->key);
}
......@@ -90,20 +91,20 @@ static struct sk_buff *named_prepare_buf(struct net *net, u32 type, u32 size,
/**
* tipc_named_publish - tell other nodes about a new publication by this node
* @net: the associated network namespace
* @publ: the new publication
* @p: the new publication
*/
struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ)
struct sk_buff *tipc_named_publish(struct net *net, struct publication *p)
{
struct name_table *nt = tipc_name_table(net);
struct distr_item *item;
struct sk_buff *skb;
if (publ->scope == TIPC_NODE_SCOPE) {
list_add_tail_rcu(&publ->binding_node, &nt->node_scope);
if (p->scope == TIPC_NODE_SCOPE) {
list_add_tail_rcu(&p->binding_node, &nt->node_scope);
return NULL;
}
write_lock_bh(&nt->cluster_scope_lock);
list_add_tail(&publ->binding_node, &nt->cluster_scope);
list_add_tail(&p->binding_node, &nt->cluster_scope);
write_unlock_bh(&nt->cluster_scope_lock);
skb = named_prepare_buf(net, PUBLICATION, ITEM_SIZE, 0);
if (!skb) {
......@@ -113,25 +114,25 @@ struct sk_buff *tipc_named_publish(struct net *net, struct publication *publ)
msg_set_named_seqno(buf_msg(skb), nt->snd_nxt++);
msg_set_non_legacy(buf_msg(skb));
item = (struct distr_item *)msg_data(buf_msg(skb));
publ_to_item(item, publ);
publ_to_item(item, p);
return skb;
}
/**
* tipc_named_withdraw - tell other nodes about a withdrawn publication by this node
* @net: the associated network namespace
* @publ: the withdrawn publication
* @p: the withdrawn publication
*/
struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *p)
{
struct name_table *nt = tipc_name_table(net);
struct distr_item *item;
struct sk_buff *skb;
write_lock_bh(&nt->cluster_scope_lock);
list_del(&publ->binding_node);
list_del(&p->binding_node);
write_unlock_bh(&nt->cluster_scope_lock);
if (publ->scope == TIPC_NODE_SCOPE)
if (p->scope == TIPC_NODE_SCOPE)
return NULL;
skb = named_prepare_buf(net, WITHDRAWAL, ITEM_SIZE, 0);
......@@ -142,7 +143,7 @@ struct sk_buff *tipc_named_withdraw(struct net *net, struct publication *publ)
msg_set_named_seqno(buf_msg(skb), nt->snd_nxt++);
msg_set_non_legacy(buf_msg(skb));
item = (struct distr_item *)msg_data(buf_msg(skb));
publ_to_item(item, publ);
publ_to_item(item, p);
return skb;
}
......@@ -233,33 +234,27 @@ void tipc_named_node_up(struct net *net, u32 dnode, u16 capabilities)
/**
* tipc_publ_purge - remove publication associated with a failed node
* @net: the associated network namespace
* @publ: the publication to remove
* @p: the publication to remove
* @addr: failed node's address
*
* Invoked for each publication issued by a newly failed node.
* Removes publication structure from name table & deletes it.
*/
static void tipc_publ_purge(struct net *net, struct publication *publ, u32 addr)
static void tipc_publ_purge(struct net *net, struct publication *p, u32 addr)
{
struct tipc_net *tn = tipc_net(net);
struct publication *p;
struct publication *_p;
struct tipc_uaddr ua;
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, p->scope, p->sr.type,
p->sr.lower, p->sr.upper);
spin_lock_bh(&tn->nametbl_lock);
p = tipc_nametbl_remove_publ(net, publ->type, publ->lower, publ->upper,
publ->node, publ->key);
if (p)
tipc_node_unsubscribe(net, &p->binding_node, addr);
_p = tipc_nametbl_remove_publ(net, &ua, &p->sk, p->key);
if (_p)
tipc_node_unsubscribe(net, &_p->binding_node, addr);
spin_unlock_bh(&tn->nametbl_lock);
if (p != publ) {
pr_err("Unable to remove publication from failed node\n"
" (type=%u, lower=%u, node=0x%x, port=%u, key=%u)\n",
publ->type, publ->lower, publ->node, publ->port,
publ->key);
}
if (p)
kfree_rcu(p, rcu);
if (_p)
kfree_rcu(_p, rcu);
}
void tipc_publ_notify(struct net *net, struct list_head *nsub_list,
......@@ -293,30 +288,30 @@ static bool tipc_update_nametbl(struct net *net, struct distr_item *i,
u32 node, u32 dtype)
{
struct publication *p = NULL;
u32 lower = ntohl(i->lower);
u32 upper = ntohl(i->upper);
u32 type = ntohl(i->type);
u32 port = ntohl(i->port);
struct tipc_socket_addr sk;
struct tipc_uaddr ua;
u32 key = ntohl(i->key);
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,
ntohl(i->type), ntohl(i->lower), ntohl(i->upper));
sk.ref = ntohl(i->port);
sk.node = node;
if (dtype == PUBLICATION) {
p = tipc_nametbl_insert_publ(net, type, lower, upper,
TIPC_CLUSTER_SCOPE, node,
port, key);
p = tipc_nametbl_insert_publ(net, &ua, &sk, key);
if (p) {
tipc_node_subscribe(net, &p->binding_node, node);
return true;
}
} else if (dtype == WITHDRAWAL) {
p = tipc_nametbl_remove_publ(net, type, lower,
upper, node, key);
p = tipc_nametbl_remove_publ(net, &ua, &sk, key);
if (p) {
tipc_node_unsubscribe(net, &p->binding_node, node);
kfree_rcu(p, rcu);
return true;
}
pr_warn_ratelimited("Failed to remove binding %u,%u from %x\n",
type, lower, node);
pr_warn_ratelimited("Failed to remove binding %u,%u from %u\n",
ua.sr.type, ua.sr.lower, node);
} else {
pr_warn("Unrecognized name table message received\n");
}
......@@ -410,15 +405,15 @@ void tipc_named_reinit(struct net *net)
{
struct name_table *nt = tipc_name_table(net);
struct tipc_net *tn = tipc_net(net);
struct publication *publ;
struct publication *p;
u32 self = tipc_own_addr(net);
spin_lock_bh(&tn->nametbl_lock);
list_for_each_entry_rcu(publ, &nt->node_scope, binding_node)
publ->node = self;
list_for_each_entry_rcu(publ, &nt->cluster_scope, binding_node)
publ->node = self;
list_for_each_entry_rcu(p, &nt->node_scope, binding_node)
p->sk.node = self;
list_for_each_entry_rcu(p, &nt->cluster_scope, binding_node)
p->sk.node = self;
nt->rc_dests = 0;
spin_unlock_bh(&tn->nametbl_lock);
}
This diff is collapsed.
......@@ -3,6 +3,7 @@
*
* Copyright (c) 2000-2006, 2014-2018, Ericsson AB
* Copyright (c) 2004-2005, 2010-2011, Wind River Systems
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -41,6 +42,7 @@ struct tipc_subscription;
struct tipc_plist;
struct tipc_nlist;
struct tipc_group;
struct tipc_uaddr;
/*
* TIPC name types reserved for internal TIPC use (both current and planned)
......@@ -50,13 +52,10 @@ struct tipc_group;
#define TIPC_NAMETBL_SIZE 1024 /* must be a power of 2 */
/**
* struct publication - info about a published (name or) name sequence
* @type: name sequence type
* @lower: name sequence lower bound
* @upper: name sequence upper bound
* struct publication - info about a published service address or range
* @sr: service range represented by this publication
* @sk: address of socket bound to this publication
* @scope: scope of publication, TIPC_NODE_SCOPE or TIPC_CLUSTER_SCOPE
* @node: network address of publishing socket's node
* @port: publishing port
* @key: publication key, unique across the cluster
* @id: publication id
* @binding_node: all publications from the same node which bound this one
......@@ -74,12 +73,9 @@ struct tipc_group;
* @rcu: RCU callback head used for deferred freeing
*/
struct publication {
u32 type;
u32 lower;
u32 upper;
u32 scope;
u32 node;
u32 port;
struct tipc_service_range sr;
struct tipc_socket_addr sk;
u16 scope;
u32 key;
u32 id;
struct list_head binding_node;
......@@ -114,28 +110,29 @@ struct name_table {
};
int tipc_nl_name_table_dump(struct sk_buff *skb, struct netlink_callback *cb);
u32 tipc_nametbl_translate(struct net *net, u32 type, u32 instance, u32 *node);
void tipc_nametbl_mc_lookup(struct net *net, u32 type, u32 lower, u32 upper,
u32 scope, bool exact, struct list_head *dports);
bool tipc_nametbl_lookup_anycast(struct net *net, struct tipc_uaddr *ua,
struct tipc_socket_addr *sk);
void tipc_nametbl_lookup_mcast_sockets(struct net *net, struct tipc_uaddr *ua,
bool exact, struct list_head *dports);
void tipc_nametbl_lookup_mcast_nodes(struct net *net, struct tipc_uaddr *ua,
struct tipc_nlist *nodes);
bool tipc_nametbl_lookup_group(struct net *net, struct tipc_uaddr *ua,
struct list_head *dsts, int *dstcnt,
u32 exclude, bool mcast);
void tipc_nametbl_build_group(struct net *net, struct tipc_group *grp,
u32 type, u32 domain);
void tipc_nametbl_lookup_dst_nodes(struct net *net, u32 type, u32 lower,
u32 upper, struct tipc_nlist *nodes);
bool tipc_nametbl_lookup(struct net *net, u32 type, u32 instance, u32 domain,
struct list_head *dsts, int *dstcnt, u32 exclude,
bool all);
struct publication *tipc_nametbl_publish(struct net *net, u32 type, u32 lower,
u32 upper, u32 scope, u32 port,
u32 key);
int tipc_nametbl_withdraw(struct net *net, u32 type, u32 lower, u32 upper,
u32 key);
struct publication *tipc_nametbl_insert_publ(struct net *net, u32 type,
u32 lower, u32 upper, u32 scope,
u32 node, u32 ref, u32 key);
struct publication *tipc_nametbl_remove_publ(struct net *net, u32 type,
u32 lower, u32 upper,
u32 node, u32 key);
struct tipc_uaddr *ua);
struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,
struct tipc_socket_addr *sk, u32 key);
void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,
struct tipc_socket_addr *sk, u32 key);
struct publication *tipc_nametbl_insert_publ(struct net *net,
struct tipc_uaddr *ua,
struct tipc_socket_addr *sk,
u32 key);
struct publication *tipc_nametbl_remove_publ(struct net *net,
struct tipc_uaddr *ua,
struct tipc_socket_addr *sk,
u32 key);
bool tipc_nametbl_subscribe(struct tipc_subscription *s);
void tipc_nametbl_unsubscribe(struct tipc_subscription *s);
int tipc_nametbl_init(struct net *net);
......
......@@ -125,6 +125,11 @@ int tipc_net_init(struct net *net, u8 *node_id, u32 addr)
static void tipc_net_finalize(struct net *net, u32 addr)
{
struct tipc_net *tn = tipc_net(net);
struct tipc_socket_addr sk = {0, addr};
struct tipc_uaddr ua;
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_CLUSTER_SCOPE,
TIPC_NODE_STATE, addr, addr);
if (cmpxchg(&tn->node_addr, 0, addr))
return;
......@@ -132,8 +137,7 @@ static void tipc_net_finalize(struct net *net, u32 addr)
tipc_named_reinit(net);
tipc_sk_reinit(net);
tipc_mon_reinit_self(net);
tipc_nametbl_publish(net, TIPC_NODE_STATE, addr, addr,
TIPC_CLUSTER_SCOPE, 0, addr);
tipc_nametbl_publish(net, &ua, &sk, addr);
}
void tipc_net_finalize_work(struct work_struct *work)
......
......@@ -398,21 +398,23 @@ static void tipc_node_write_unlock_fast(struct tipc_node *n)
static void tipc_node_write_unlock(struct tipc_node *n)
__releases(n->lock)
{
struct tipc_socket_addr sk;
struct net *net = n->net;
u32 addr = 0;
u32 flags = n->action_flags;
u32 link_id = 0;
u32 bearer_id;
struct list_head *publ_list;
struct tipc_uaddr ua;
u32 bearer_id;
if (likely(!flags)) {
write_unlock_bh(&n->lock);
return;
}
addr = n->addr;
link_id = n->link_id;
bearer_id = link_id & 0xffff;
tipc_uaddr(&ua, TIPC_SERVICE_RANGE, TIPC_NODE_SCOPE,
TIPC_LINK_STATE, n->addr, n->addr);
sk.ref = n->link_id;
sk.node = n->addr;
bearer_id = n->link_id & 0xffff;
publ_list = &n->publ_list;
n->action_flags &= ~(TIPC_NOTIFY_NODE_DOWN | TIPC_NOTIFY_NODE_UP |
......@@ -421,20 +423,18 @@ static void tipc_node_write_unlock(struct tipc_node *n)
write_unlock_bh(&n->lock);
if (flags & TIPC_NOTIFY_NODE_DOWN)
tipc_publ_notify(net, publ_list, addr, n->capabilities);
tipc_publ_notify(net, publ_list, n->addr, n->capabilities);
if (flags & TIPC_NOTIFY_NODE_UP)
tipc_named_node_up(net, addr, n->capabilities);
tipc_named_node_up(net, n->addr, n->capabilities);
if (flags & TIPC_NOTIFY_LINK_UP) {
tipc_mon_peer_up(net, addr, bearer_id);
tipc_nametbl_publish(net, TIPC_LINK_STATE, addr, addr,
TIPC_NODE_SCOPE, link_id, link_id);
tipc_mon_peer_up(net, n->addr, bearer_id);
tipc_nametbl_publish(net, &ua, &sk, n->link_id);
}
if (flags & TIPC_NOTIFY_LINK_DOWN) {
tipc_mon_peer_down(net, addr, bearer_id);
tipc_nametbl_withdraw(net, TIPC_LINK_STATE, addr,
addr, link_id);
tipc_mon_peer_down(net, n->addr, bearer_id);
tipc_nametbl_withdraw(net, &ua, &sk, n->link_id);
}
}
......
This diff is collapsed.
......@@ -3,7 +3,7 @@
*
* Copyright (c) 2000-2017, Ericsson AB
* Copyright (c) 2005-2007, 2010-2013, Wind River Systems
* Copyright (c) 2020, Red Hat Inc
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -40,77 +40,75 @@
#include "subscr.h"
static void tipc_sub_send_event(struct tipc_subscription *sub,
u32 found_lower, u32 found_upper,
u32 event, u32 port, u32 node)
struct publication *p,
u32 event)
{
struct tipc_subscr *s = &sub->evt.s;
struct tipc_event *evt = &sub->evt;
if (sub->inactive)
return;
tipc_evt_write(evt, event, event);
tipc_evt_write(evt, found_lower, found_lower);
tipc_evt_write(evt, found_upper, found_upper);
tipc_evt_write(evt, port.ref, port);
tipc_evt_write(evt, port.node, node);
if (p) {
tipc_evt_write(evt, found_lower, p->sr.lower);
tipc_evt_write(evt, found_upper, p->sr.upper);
tipc_evt_write(evt, port.ref, p->sk.ref);
tipc_evt_write(evt, port.node, p->sk.node);
} else {
tipc_evt_write(evt, found_lower, s->seq.lower);
tipc_evt_write(evt, found_upper, s->seq.upper);
tipc_evt_write(evt, port.ref, 0);
tipc_evt_write(evt, port.node, 0);
}
tipc_topsrv_queue_evt(sub->net, sub->conid, event, evt);
}
/**
* tipc_sub_check_overlap - test for subscription overlap with the given values
* @seq: tipc_name_seq to check
* @found_lower: lower value to test
* @found_upper: upper value to test
* @subscribed: the service range subscribed for
* @found: the service range we are checning for match
*
* Return: 1 if there is overlap, otherwise 0.
* Returns true if there is overlap, otherwise false.
*/
int tipc_sub_check_overlap(struct tipc_service_range *seq, u32 found_lower,
u32 found_upper)
static bool tipc_sub_check_overlap(struct tipc_service_range *subscribed,
struct tipc_service_range *found)
{
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;
u32 found_lower = found->lower;
u32 found_upper = found->upper;
if (found_lower < subscribed->lower)
found_lower = subscribed->lower;
if (found_upper > subscribed->upper)
found_upper = subscribed->upper;
return found_lower <= found_upper;
}
void tipc_sub_report_overlap(struct tipc_subscription *sub,
u32 found_lower, u32 found_upper,
u32 event, u32 port, u32 node,
u32 scope, int must)
struct publication *p,
u32 event, bool must)
{
struct tipc_subscr *s = &sub->evt.s;
u32 filter = tipc_sub_read(s, filter);
struct tipc_service_range seq;
struct tipc_service_range *sr = &sub->s.seq;
u32 filter = sub->s.filter;
seq.type = tipc_sub_read(s, seq.type);
seq.lower = tipc_sub_read(s, seq.lower);
seq.upper = tipc_sub_read(s, seq.upper);
if (!tipc_sub_check_overlap(&seq, found_lower, found_upper))
if (!tipc_sub_check_overlap(sr, &p->sr))
return;
if (!must && !(filter & TIPC_SUB_PORTS))
return;
if (filter & TIPC_SUB_CLUSTER_SCOPE && scope == TIPC_NODE_SCOPE)
if (filter & TIPC_SUB_CLUSTER_SCOPE && p->scope == TIPC_NODE_SCOPE)
return;
if (filter & TIPC_SUB_NODE_SCOPE && scope != TIPC_NODE_SCOPE)
if (filter & TIPC_SUB_NODE_SCOPE && p->scope != TIPC_NODE_SCOPE)
return;
spin_lock(&sub->lock);
tipc_sub_send_event(sub, found_lower, found_upper,
event, port, node);
tipc_sub_send_event(sub, p, event);
spin_unlock(&sub->lock);
}
static void tipc_sub_timeout(struct timer_list *t)
{
struct tipc_subscription *sub = from_timer(sub, t, timer);
struct tipc_subscr *s = &sub->evt.s;
spin_lock(&sub->lock);
tipc_sub_send_event(sub, s->seq.lower, s->seq.upper,
TIPC_SUBSCR_TIMEOUT, 0, 0);
tipc_sub_send_event(sub, NULL, TIPC_SUBSCR_TIMEOUT);
sub->inactive = true;
spin_unlock(&sub->lock);
}
......@@ -134,12 +132,14 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net,
struct tipc_subscr *s,
int conid)
{
u32 lower = tipc_sub_read(s, seq.lower);
u32 upper = tipc_sub_read(s, seq.upper);
u32 filter = tipc_sub_read(s, filter);
struct tipc_subscription *sub;
u32 timeout;
if ((filter & TIPC_SUB_PORTS && filter & TIPC_SUB_SERVICE) ||
(tipc_sub_read(s, seq.lower) > tipc_sub_read(s, seq.upper))) {
lower > upper) {
pr_warn("Subscription rejected, illegal request\n");
return NULL;
}
......@@ -154,6 +154,12 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net,
sub->conid = conid;
sub->inactive = false;
memcpy(&sub->evt.s, s, sizeof(*s));
sub->s.seq.type = tipc_sub_read(s, seq.type);
sub->s.seq.lower = lower;
sub->s.seq.upper = upper;
sub->s.filter = filter;
sub->s.timeout = tipc_sub_read(s, timeout);
memcpy(sub->s.usr_handle, s->usr_handle, 8);
spin_lock_init(&sub->lock);
kref_init(&sub->kref);
if (!tipc_nametbl_subscribe(sub)) {
......
......@@ -3,7 +3,7 @@
*
* Copyright (c) 2003-2017, Ericsson AB
* Copyright (c) 2005-2007, 2012-2013, Wind River Systems
* Copyright (c) 2020, Red Hat Inc
* Copyright (c) 2020-2021, Red Hat Inc
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
......@@ -43,6 +43,7 @@
#define TIPC_MAX_SUBSCR 65535
#define TIPC_MAX_PUBL 65535
struct publication;
struct tipc_subscription;
struct tipc_conn;
......@@ -59,12 +60,13 @@ struct tipc_conn;
* @lock: serialize up/down and timer events
*/
struct tipc_subscription {
struct tipc_subscr s;
struct tipc_event evt;
struct kref kref;
struct net *net;
struct timer_list timer;
struct list_head service_list;
struct list_head sub_list;
struct tipc_event evt;
int conid;
bool inactive;
spinlock_t lock;
......@@ -74,13 +76,9 @@ struct tipc_subscription *tipc_sub_subscribe(struct net *net,
struct tipc_subscr *s,
int conid);
void tipc_sub_unsubscribe(struct tipc_subscription *sub);
int tipc_sub_check_overlap(struct tipc_service_range *seq,
u32 found_lower, u32 found_upper);
void tipc_sub_report_overlap(struct tipc_subscription *sub,
u32 found_lower, u32 found_upper,
u32 event, u32 port, u32 node,
u32 scope, int must);
struct publication *p,
u32 event, bool must);
int __net_init tipc_topsrv_init_net(struct net *net);
void __net_exit tipc_topsrv_exit_net(struct net *net);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment