linux/net/rxrpc/local_event.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2/* AF_RXRPC local endpoint management
   3 *
   4 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
   5 * Written by David Howells (dhowells@redhat.com)
   6 */
   7
   8#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
   9
  10#include <linux/module.h>
  11#include <linux/net.h>
  12#include <linux/skbuff.h>
  13#include <linux/slab.h>
  14#include <net/sock.h>
  15#include <net/af_rxrpc.h>
  16#include <generated/utsrelease.h>
  17#include "ar-internal.h"
  18
  19static const char rxrpc_version_string[65] = "linux-" UTS_RELEASE " AF_RXRPC";
  20
  21/*
  22 * Reply to a version request
  23 */
  24static void rxrpc_send_version_request(struct rxrpc_local *local,
  25                                       struct rxrpc_host_header *hdr,
  26                                       struct sk_buff *skb)
  27{
  28        struct rxrpc_wire_header whdr;
  29        struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  30        struct sockaddr_rxrpc srx;
  31        struct msghdr msg;
  32        struct kvec iov[2];
  33        size_t len;
  34        int ret;
  35
  36        _enter("");
  37
  38        if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
  39                return;
  40
  41        msg.msg_name    = &srx.transport;
  42        msg.msg_namelen = srx.transport_len;
  43        msg.msg_control = NULL;
  44        msg.msg_controllen = 0;
  45        msg.msg_flags   = 0;
  46
  47        whdr.epoch      = htonl(sp->hdr.epoch);
  48        whdr.cid        = htonl(sp->hdr.cid);
  49        whdr.callNumber = htonl(sp->hdr.callNumber);
  50        whdr.seq        = 0;
  51        whdr.serial     = 0;
  52        whdr.type       = RXRPC_PACKET_TYPE_VERSION;
  53        whdr.flags      = RXRPC_LAST_PACKET | (~hdr->flags & RXRPC_CLIENT_INITIATED);
  54        whdr.userStatus = 0;
  55        whdr.securityIndex = 0;
  56        whdr._rsvd      = 0;
  57        whdr.serviceId  = htons(sp->hdr.serviceId);
  58
  59        iov[0].iov_base = &whdr;
  60        iov[0].iov_len  = sizeof(whdr);
  61        iov[1].iov_base = (char *)rxrpc_version_string;
  62        iov[1].iov_len  = sizeof(rxrpc_version_string);
  63
  64        len = iov[0].iov_len + iov[1].iov_len;
  65
  66        _proto("Tx VERSION (reply)");
  67
  68        ret = kernel_sendmsg(local->socket, &msg, iov, 2, len);
  69        if (ret < 0)
  70                trace_rxrpc_tx_fail(local->debug_id, 0, ret,
  71                                    rxrpc_tx_point_version_reply);
  72        else
  73                trace_rxrpc_tx_packet(local->debug_id, &whdr,
  74                                      rxrpc_tx_point_version_reply);
  75
  76        _leave("");
  77}
  78
  79/*
  80 * Process event packets targetted at a local endpoint.
  81 */
  82void rxrpc_process_local_events(struct rxrpc_local *local)
  83{
  84        struct sk_buff *skb;
  85        char v;
  86
  87        _enter("");
  88
  89        skb = skb_dequeue(&local->event_queue);
  90        if (skb) {
  91                struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
  92
  93                rxrpc_see_skb(skb, rxrpc_skb_seen);
  94                _debug("{%d},{%u}", local->debug_id, sp->hdr.type);
  95
  96                switch (sp->hdr.type) {
  97                case RXRPC_PACKET_TYPE_VERSION:
  98                        if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
  99                                          &v, 1) < 0)
 100                                return;
 101                        _proto("Rx VERSION { %02x }", v);
 102                        if (v == 0)
 103                                rxrpc_send_version_request(local, &sp->hdr, skb);
 104                        break;
 105
 106                default:
 107                        /* Just ignore anything we don't understand */
 108                        break;
 109                }
 110
 111                rxrpc_free_skb(skb, rxrpc_skb_freed);
 112        }
 113
 114        _leave("");
 115}
 116