net/x25/x25_link.c

Source file repositories/reference/linux-study-clean/net/x25/x25_link.c

File Facts

System
Linux kernel
Corpus path
net/x25/x25_link.c
Extension
.c
Size
9241 bytes
Lines
422
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

switch (nb->state) {
		case X25_LINK_STATE_0:
			/* This can happen when the x25 module just gets loaded
			 * and doesn't know layer 2 has already connected
			 */
			nb->state = X25_LINK_STATE_3;
			x25_transmit_restart_confirmation(nb);
			break;
		case X25_LINK_STATE_2:
			x25_stop_t20timer(nb);
			nb->state = X25_LINK_STATE_3;
			break;
		case X25_LINK_STATE_3:
			/* clear existing virtual calls */
			x25_kill_by_neigh(nb);

			x25_transmit_restart_confirmation(nb);
			break;
		}
		break;

	case X25_RESTART_CONFIRMATION:
		switch (nb->state) {
		case X25_LINK_STATE_2:
			x25_stop_t20timer(nb);
			nb->state = X25_LINK_STATE_3;
			break;
		case X25_LINK_STATE_3:
			/* clear existing virtual calls */
			x25_kill_by_neigh(nb);

			x25_transmit_restart_request(nb);
			nb->state = X25_LINK_STATE_2;
			x25_start_t20timer(nb);
			break;
		}
		break;

	case X25_DIAGNOSTIC:
		if (!pskb_may_pull(skb, X25_STD_MIN_LEN + 4))
			break;

		pr_warn("diagnostic #%d - %02X %02X %02X\n",
		       skb->data[3], skb->data[4],
		       skb->data[5], skb->data[6]);
		break;

	default:
		pr_warn("received unknown %02X with LCI 000\n",
		       frametype);
		break;
	}

	if (nb->state == X25_LINK_STATE_3)
		while ((skbn = skb_dequeue(&nb->queue)) != NULL)
			x25_send_frame(skbn, nb);
}

/*
 *	This routine is called when a Restart Request is needed
 */
static void x25_transmit_restart_request(struct x25_neigh *nb)
{
	unsigned char *dptr;
	int len = X25_MAX_L2_LEN + X25_STD_MIN_LEN + 2;
	struct sk_buff *skb = alloc_skb(len, GFP_ATOMIC);

	if (!skb)
		return;

	skb_reserve(skb, X25_MAX_L2_LEN);

	dptr = skb_put(skb, X25_STD_MIN_LEN + 2);

	*dptr++ = nb->extended ? X25_GFI_EXTSEQ : X25_GFI_STDSEQ;
	*dptr++ = 0x00;
	*dptr++ = X25_RESTART_REQUEST;
	*dptr++ = 0x00;
	*dptr++ = 0;

	skb->sk = NULL;

	x25_send_frame(skb, nb);
}

/*
 * This routine is called when a Restart Confirmation is needed
 */
static void x25_transmit_restart_confirmation(struct x25_neigh *nb)
{

Annotation

Implementation Notes