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

hdlc_raw_eth.c (3075B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Generic HDLC support routines for Linux
      4 * HDLC Ethernet emulation support
      5 *
      6 * Copyright (C) 2002-2006 Krzysztof Halasa <khc@pm.waw.pl>
      7 */
      8
      9#include <linux/errno.h>
     10#include <linux/etherdevice.h>
     11#include <linux/gfp.h>
     12#include <linux/hdlc.h>
     13#include <linux/if_arp.h>
     14#include <linux/inetdevice.h>
     15#include <linux/init.h>
     16#include <linux/kernel.h>
     17#include <linux/module.h>
     18#include <linux/pkt_sched.h>
     19#include <linux/poll.h>
     20#include <linux/rtnetlink.h>
     21#include <linux/skbuff.h>
     22
     23static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs);
     24
     25static netdev_tx_t eth_tx(struct sk_buff *skb, struct net_device *dev)
     26{
     27	int pad = ETH_ZLEN - skb->len;
     28	if (pad > 0) {		/* Pad the frame with zeros */
     29		int len = skb->len;
     30		if (skb_tailroom(skb) < pad)
     31			if (pskb_expand_head(skb, 0, pad, GFP_ATOMIC)) {
     32				dev->stats.tx_dropped++;
     33				dev_kfree_skb(skb);
     34				return 0;
     35			}
     36		skb_put(skb, pad);
     37		memset(skb->data + len, 0, pad);
     38	}
     39	return dev_to_hdlc(dev)->xmit(skb, dev);
     40}
     41
     42
     43static struct hdlc_proto proto = {
     44	.type_trans	= eth_type_trans,
     45	.xmit		= eth_tx,
     46	.ioctl		= raw_eth_ioctl,
     47	.module		= THIS_MODULE,
     48};
     49
     50
     51static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs)
     52{
     53	raw_hdlc_proto __user *raw_s = ifs->ifs_ifsu.raw_hdlc;
     54	const size_t size = sizeof(raw_hdlc_proto);
     55	raw_hdlc_proto new_settings;
     56	hdlc_device *hdlc = dev_to_hdlc(dev);
     57	unsigned int old_qlen;
     58	int result;
     59
     60	switch (ifs->type) {
     61	case IF_GET_PROTO:
     62		if (dev_to_hdlc(dev)->proto != &proto)
     63			return -EINVAL;
     64		ifs->type = IF_PROTO_HDLC_ETH;
     65		if (ifs->size < size) {
     66			ifs->size = size; /* data size wanted */
     67			return -ENOBUFS;
     68		}
     69		if (copy_to_user(raw_s, hdlc->state, size))
     70			return -EFAULT;
     71		return 0;
     72
     73	case IF_PROTO_HDLC_ETH:
     74		if (!capable(CAP_NET_ADMIN))
     75			return -EPERM;
     76
     77		if (dev->flags & IFF_UP)
     78			return -EBUSY;
     79
     80		if (copy_from_user(&new_settings, raw_s, size))
     81			return -EFAULT;
     82
     83		if (new_settings.encoding == ENCODING_DEFAULT)
     84			new_settings.encoding = ENCODING_NRZ;
     85
     86		if (new_settings.parity == PARITY_DEFAULT)
     87			new_settings.parity = PARITY_CRC16_PR1_CCITT;
     88
     89		result = hdlc->attach(dev, new_settings.encoding,
     90				      new_settings.parity);
     91		if (result)
     92			return result;
     93
     94		result = attach_hdlc_protocol(dev, &proto,
     95					      sizeof(raw_hdlc_proto));
     96		if (result)
     97			return result;
     98		memcpy(hdlc->state, &new_settings, size);
     99		old_qlen = dev->tx_queue_len;
    100		ether_setup(dev);
    101		dev->tx_queue_len = old_qlen;
    102		dev->priv_flags &= ~IFF_TX_SKB_SHARING;
    103		eth_hw_addr_random(dev);
    104		call_netdevice_notifiers(NETDEV_POST_TYPE_CHANGE, dev);
    105		netif_dormant_off(dev);
    106		return 0;
    107	}
    108
    109	return -EINVAL;
    110}
    111
    112
    113static int __init hdlc_eth_init(void)
    114{
    115	register_hdlc_protocol(&proto);
    116	return 0;
    117}
    118
    119
    120
    121static void __exit hdlc_eth_exit(void)
    122{
    123	unregister_hdlc_protocol(&proto);
    124}
    125
    126
    127module_init(hdlc_eth_init);
    128module_exit(hdlc_eth_exit);
    129
    130MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
    131MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC");
    132MODULE_LICENSE("GPL v2");