cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

lapb_out.c (4800B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *	LAPB release 002
      4 *
      5 *	This code REQUIRES 2.1.15 or higher/ NET3.038
      6 *
      7 *	History
      8 *	LAPB 001	Jonathan Naylor	Started Coding
      9 *	LAPB 002	Jonathan Naylor	New timer architecture.
     10 */
     11
     12#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
     13
     14#include <linux/errno.h>
     15#include <linux/types.h>
     16#include <linux/socket.h>
     17#include <linux/in.h>
     18#include <linux/kernel.h>
     19#include <linux/timer.h>
     20#include <linux/string.h>
     21#include <linux/sockios.h>
     22#include <linux/net.h>
     23#include <linux/inet.h>
     24#include <linux/skbuff.h>
     25#include <linux/slab.h>
     26#include <net/sock.h>
     27#include <linux/uaccess.h>
     28#include <linux/fcntl.h>
     29#include <linux/mm.h>
     30#include <linux/interrupt.h>
     31#include <net/lapb.h>
     32
     33/*
     34 *  This procedure is passed a buffer descriptor for an iframe. It builds
     35 *  the rest of the control part of the frame and then writes it out.
     36 */
     37static void lapb_send_iframe(struct lapb_cb *lapb, struct sk_buff *skb, int poll_bit)
     38{
     39	unsigned char *frame;
     40
     41	if (!skb)
     42		return;
     43
     44	if (lapb->mode & LAPB_EXTENDED) {
     45		frame = skb_push(skb, 2);
     46
     47		frame[0] = LAPB_I;
     48		frame[0] |= lapb->vs << 1;
     49		frame[1] = poll_bit ? LAPB_EPF : 0;
     50		frame[1] |= lapb->vr << 1;
     51	} else {
     52		frame = skb_push(skb, 1);
     53
     54		*frame = LAPB_I;
     55		*frame |= poll_bit ? LAPB_SPF : 0;
     56		*frame |= lapb->vr << 5;
     57		*frame |= lapb->vs << 1;
     58	}
     59
     60	lapb_dbg(1, "(%p) S%d TX I(%d) S%d R%d\n",
     61		 lapb->dev, lapb->state, poll_bit, lapb->vs, lapb->vr);
     62
     63	lapb_transmit_buffer(lapb, skb, LAPB_COMMAND);
     64}
     65
     66void lapb_kick(struct lapb_cb *lapb)
     67{
     68	struct sk_buff *skb, *skbn;
     69	unsigned short modulus, start, end;
     70
     71	modulus = (lapb->mode & LAPB_EXTENDED) ? LAPB_EMODULUS : LAPB_SMODULUS;
     72	start = !skb_peek(&lapb->ack_queue) ? lapb->va : lapb->vs;
     73	end   = (lapb->va + lapb->window) % modulus;
     74
     75	if (!(lapb->condition & LAPB_PEER_RX_BUSY_CONDITION) &&
     76	    start != end && skb_peek(&lapb->write_queue)) {
     77		lapb->vs = start;
     78
     79		/*
     80		 * Dequeue the frame and copy it.
     81		 */
     82		skb = skb_dequeue(&lapb->write_queue);
     83
     84		do {
     85			skbn = skb_copy(skb, GFP_ATOMIC);
     86			if (!skbn) {
     87				skb_queue_head(&lapb->write_queue, skb);
     88				break;
     89			}
     90
     91			if (skb->sk)
     92				skb_set_owner_w(skbn, skb->sk);
     93
     94			/*
     95			 * Transmit the frame copy.
     96			 */
     97			lapb_send_iframe(lapb, skbn, LAPB_POLLOFF);
     98
     99			lapb->vs = (lapb->vs + 1) % modulus;
    100
    101			/*
    102			 * Requeue the original data frame.
    103			 */
    104			skb_queue_tail(&lapb->ack_queue, skb);
    105
    106		} while (lapb->vs != end && (skb = skb_dequeue(&lapb->write_queue)) != NULL);
    107
    108		lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
    109
    110		if (!lapb_t1timer_running(lapb))
    111			lapb_start_t1timer(lapb);
    112	}
    113}
    114
    115void lapb_transmit_buffer(struct lapb_cb *lapb, struct sk_buff *skb, int type)
    116{
    117	unsigned char *ptr;
    118
    119	ptr = skb_push(skb, 1);
    120
    121	if (lapb->mode & LAPB_MLP) {
    122		if (lapb->mode & LAPB_DCE) {
    123			if (type == LAPB_COMMAND)
    124				*ptr = LAPB_ADDR_C;
    125			if (type == LAPB_RESPONSE)
    126				*ptr = LAPB_ADDR_D;
    127		} else {
    128			if (type == LAPB_COMMAND)
    129				*ptr = LAPB_ADDR_D;
    130			if (type == LAPB_RESPONSE)
    131				*ptr = LAPB_ADDR_C;
    132		}
    133	} else {
    134		if (lapb->mode & LAPB_DCE) {
    135			if (type == LAPB_COMMAND)
    136				*ptr = LAPB_ADDR_A;
    137			if (type == LAPB_RESPONSE)
    138				*ptr = LAPB_ADDR_B;
    139		} else {
    140			if (type == LAPB_COMMAND)
    141				*ptr = LAPB_ADDR_B;
    142			if (type == LAPB_RESPONSE)
    143				*ptr = LAPB_ADDR_A;
    144		}
    145	}
    146
    147	lapb_dbg(2, "(%p) S%d TX %3ph\n", lapb->dev, lapb->state, skb->data);
    148
    149	if (!lapb_data_transmit(lapb, skb))
    150		kfree_skb(skb);
    151}
    152
    153void lapb_establish_data_link(struct lapb_cb *lapb)
    154{
    155	lapb->condition = 0x00;
    156	lapb->n2count   = 0;
    157
    158	if (lapb->mode & LAPB_EXTENDED) {
    159		lapb_dbg(1, "(%p) S%d TX SABME(1)\n", lapb->dev, lapb->state);
    160		lapb_send_control(lapb, LAPB_SABME, LAPB_POLLON, LAPB_COMMAND);
    161	} else {
    162		lapb_dbg(1, "(%p) S%d TX SABM(1)\n", lapb->dev, lapb->state);
    163		lapb_send_control(lapb, LAPB_SABM, LAPB_POLLON, LAPB_COMMAND);
    164	}
    165
    166	lapb_start_t1timer(lapb);
    167	lapb_stop_t2timer(lapb);
    168}
    169
    170void lapb_enquiry_response(struct lapb_cb *lapb)
    171{
    172	lapb_dbg(1, "(%p) S%d TX RR(1) R%d\n",
    173		 lapb->dev, lapb->state, lapb->vr);
    174
    175	lapb_send_control(lapb, LAPB_RR, LAPB_POLLON, LAPB_RESPONSE);
    176
    177	lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
    178}
    179
    180void lapb_timeout_response(struct lapb_cb *lapb)
    181{
    182	lapb_dbg(1, "(%p) S%d TX RR(0) R%d\n",
    183		 lapb->dev, lapb->state, lapb->vr);
    184	lapb_send_control(lapb, LAPB_RR, LAPB_POLLOFF, LAPB_RESPONSE);
    185
    186	lapb->condition &= ~LAPB_ACK_PENDING_CONDITION;
    187}
    188
    189void lapb_check_iframes_acked(struct lapb_cb *lapb, unsigned short nr)
    190{
    191	if (lapb->vs == nr) {
    192		lapb_frames_acked(lapb, nr);
    193		lapb_stop_t1timer(lapb);
    194		lapb->n2count = 0;
    195	} else if (lapb->va != nr) {
    196		lapb_frames_acked(lapb, nr);
    197		lapb_start_t1timer(lapb);
    198	}
    199}
    200
    201void lapb_check_need_response(struct lapb_cb *lapb, int type, int pf)
    202{
    203	if (type == LAPB_COMMAND && pf)
    204		lapb_enquiry_response(lapb);
    205}