net/tipc/subscr.c

Source file repositories/reference/linux-study-clean/net/tipc/subscr.c

File Facts

System
Linux kernel
Corpus path
net/tipc/subscr.c
Extension
.c
Size
5920 bytes
Lines
184
Domain
Networking Core
Bucket
Sockets, Protocols, Packet Path, And Network Policy
Inferred role
Networking Core: implementation source
Status
source implementation candidate

Why This File Exists

Networking stack implementation surface: socket APIs, protocol dispatch, packet flow, routing, filtering, and network namespaces.

Dependency Surface

Detected Declarations

Annotated Snippet

#include "core.h"
#include "name_table.h"
#include "subscr.h"

static void tipc_sub_send_event(struct tipc_subscription *sub,
				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);
	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
 * @subscribed: the service range subscribed for
 * @found: the service range we are checking for match
 *
 * Returns true if there is overlap, otherwise false.
 */
static bool tipc_sub_check_overlap(struct tipc_service_range *subscribed,
				   struct tipc_service_range *found)
{
	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,
			     struct publication *p,
			     u32 event, bool must)
{
	struct tipc_service_range *sr = &sub->s.seq;
	u32 filter = sub->s.filter;

	if (!tipc_sub_check_overlap(sr, &p->sr))
		return;
	if (!must && !(filter & TIPC_SUB_PORTS))
		return;
	if (filter & TIPC_SUB_CLUSTER_SCOPE && p->scope == TIPC_NODE_SCOPE)
		return;
	if (filter & TIPC_SUB_NODE_SCOPE && p->scope != TIPC_NODE_SCOPE)
		return;
	spin_lock(&sub->lock);
	tipc_sub_send_event(sub, p, event);
	spin_unlock(&sub->lock);
}

static void tipc_sub_timeout(struct timer_list *t)
{
	struct tipc_subscription *sub = timer_container_of(sub, t, timer);

	spin_lock(&sub->lock);
	tipc_sub_send_event(sub, NULL, TIPC_SUBSCR_TIMEOUT);
	sub->inactive = true;
	spin_unlock(&sub->lock);
}

static void tipc_sub_kref_release(struct kref *kref)
{
	kfree(container_of(kref, struct tipc_subscription, kref));
}

void tipc_sub_put(struct tipc_subscription *subscription)
{
	kref_put(&subscription->kref, tipc_sub_kref_release);
}

void tipc_sub_get(struct tipc_subscription *subscription)
{

Annotation

Implementation Notes