linux/net/llc/llc_output.c
<<
>>
Prefs
   1/*
   2 * llc_output.c - LLC minimal output path
   3 *
   4 * Copyright (c) 1997 by Procom Technology, Inc.
   5 *               2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
   6 *
   7 * This program can be redistributed or modified under the terms of the
   8 * GNU General Public License version 2 as published by the Free Software
   9 * Foundation.
  10 * This program is distributed without any warranty or implied warranty
  11 * of merchantability or fitness for a particular purpose.
  12 *
  13 * See the GNU General Public License version 2 for more details.
  14 */
  15
  16#include <linux/if_arp.h>
  17#include <linux/if_tr.h>
  18#include <linux/netdevice.h>
  19#include <linux/trdevice.h>
  20#include <linux/skbuff.h>
  21#include <net/llc.h>
  22#include <net/llc_pdu.h>
  23
  24/**
  25 *      llc_mac_hdr_init - fills MAC header fields
  26 *      @skb: Address of the frame to initialize its MAC header
  27 *      @sa: The MAC source address
  28 *      @da: The MAC destination address
  29 *
  30 *      Fills MAC header fields, depending on MAC type. Returns 0, If MAC type
  31 *      is a valid type and initialization completes correctly 1, otherwise.
  32 */
  33int llc_mac_hdr_init(struct sk_buff *skb,
  34                     const unsigned char *sa, const unsigned char *da)
  35{
  36        int rc = 0;
  37
  38        switch (skb->dev->type) {
  39#ifdef CONFIG_TR
  40        case ARPHRD_IEEE802_TR: {
  41                struct net_device *dev = skb->dev;
  42                struct trh_hdr *trh;
  43
  44                skb_push(skb, sizeof(*trh));
  45                skb_reset_mac_header(skb);
  46                trh = tr_hdr(skb);
  47                trh->ac = AC;
  48                trh->fc = LLC_FRAME;
  49                if (sa)
  50                        memcpy(trh->saddr, sa, dev->addr_len);
  51                else
  52                        memset(trh->saddr, 0, dev->addr_len);
  53                if (da) {
  54                        memcpy(trh->daddr, da, dev->addr_len);
  55                        tr_source_route(skb, trh, dev);
  56                        skb_reset_mac_header(skb);
  57                }
  58                break;
  59        }
  60#endif
  61        case ARPHRD_ETHER:
  62        case ARPHRD_LOOPBACK: {
  63                unsigned short len = skb->len;
  64                struct ethhdr *eth;
  65
  66                skb_push(skb, sizeof(*eth));
  67                skb_reset_mac_header(skb);
  68                eth = eth_hdr(skb);
  69                eth->h_proto = htons(len);
  70                memcpy(eth->h_dest, da, ETH_ALEN);
  71                memcpy(eth->h_source, sa, ETH_ALEN);
  72                break;
  73        }
  74        default:
  75                printk(KERN_WARNING "device type not supported: %d\n",
  76                       skb->dev->type);
  77                rc = -EINVAL;
  78        }
  79        return rc;
  80}
  81
  82/**
  83 *      llc_build_and_send_ui_pkt - unitdata request interface for upper layers
  84 *      @sap: sap to use
  85 *      @skb: packet to send
  86 *      @dmac: destination mac address
  87 *      @dsap: destination sap
  88 *
  89 *      Upper layers calls this function when upper layer wants to send data
  90 *      using connection-less mode communication (UI pdu).
  91 *
  92 *      Accept data frame from network layer to be sent using connection-
  93 *      less mode communication; timeout/retries handled by network layer;
  94 *      package primitive as an event and send to SAP event handler
  95 */
  96int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb,
  97                              unsigned char *dmac, unsigned char dsap)
  98{
  99        int rc;
 100        llc_pdu_header_init(skb, LLC_PDU_TYPE_U, sap->laddr.lsap,
 101                            dsap, LLC_PDU_CMD);
 102        llc_pdu_init_as_ui_cmd(skb);
 103        rc = llc_mac_hdr_init(skb, skb->dev->dev_addr, dmac);
 104        if (likely(!rc))
 105                rc = dev_queue_xmit(skb);
 106        return rc;
 107}
 108
 109EXPORT_SYMBOL(llc_mac_hdr_init);
 110EXPORT_SYMBOL(llc_build_and_send_ui_pkt);
 111