net/can/j1939/transport.c

Source file repositories/reference/linux-study-clean/net/can/j1939/transport.c

File Facts

System
Linux kernel
Corpus path
net/can/j1939/transport.c
Extension
.c
Size
57562 bytes
Lines
2252
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

if (se_addr->src_name) {
			if (se_addr->src_name != sk_addr->dst_name)
				return false;
		} else if (se_addr->sa != sk_addr->da) {
			return false;
		}

		if (se_addr->dst_name) {
			if (se_addr->dst_name != sk_addr->src_name)
				return false;
		} else if (se_addr->da != sk_addr->sa) {
			return false;
		}
	} else {
		if (se_addr->src_name) {
			if (se_addr->src_name != sk_addr->src_name)
				return false;
		} else if (se_addr->sa != sk_addr->sa) {
			return false;
		}

		if (se_addr->dst_name) {
			if (se_addr->dst_name != sk_addr->dst_name)
				return false;
		} else if (se_addr->da != sk_addr->da) {
			return false;
		}
	}

	return true;
}

static struct
j1939_session *j1939_session_get_by_addr_locked(struct j1939_priv *priv,
						struct list_head *root,
						struct j1939_addr *addr,
						bool reverse, bool transmitter)
{
	struct j1939_session *session;

	lockdep_assert_held(&priv->active_session_list_lock);

	list_for_each_entry(session, root, active_session_list_entry) {
		j1939_session_get(session);
		if (j1939_session_match(&session->skcb.addr, addr, reverse) &&
		    session->transmission == transmitter)
			return session;
		j1939_session_put(session);
	}

	return NULL;
}

static struct
j1939_session *j1939_session_get_simple(struct j1939_priv *priv,
					struct sk_buff *skb)
{
	struct j1939_sk_buff_cb *skcb = j1939_skb_to_cb(skb);
	struct j1939_session *session;

	lockdep_assert_held(&priv->active_session_list_lock);

	list_for_each_entry(session, &priv->active_session_list,
			    active_session_list_entry) {
		j1939_session_get(session);
		if (session->skcb.addr.type == J1939_SIMPLE &&
		    session->tskey == skcb->tskey && session->sk == skb->sk)
			return session;
		j1939_session_put(session);
	}

	return NULL;
}

static struct
j1939_session *j1939_session_get_by_addr(struct j1939_priv *priv,
					 struct j1939_addr *addr,
					 bool reverse, bool transmitter)
{
	struct j1939_session *session;

	j1939_session_list_lock(priv);
	session = j1939_session_get_by_addr_locked(priv,
						   &priv->active_session_list,
						   addr, reverse, transmitter);
	j1939_session_list_unlock(priv);

	return session;
}

Annotation

Implementation Notes