Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /* AF_RXRPC local endpoint management
0003  *
0004  * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
0005  * Written by David Howells (dhowells@redhat.com)
0006  */
0007 
0008 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
0009 
0010 #include <linux/module.h>
0011 #include <linux/net.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/slab.h>
0014 #include <net/sock.h>
0015 #include <net/af_rxrpc.h>
0016 #include <generated/utsrelease.h>
0017 #include "ar-internal.h"
0018 
0019 static const char rxrpc_version_string[65] = "linux-" UTS_RELEASE " AF_RXRPC";
0020 
0021 /*
0022  * Reply to a version request
0023  */
0024 static void rxrpc_send_version_request(struct rxrpc_local *local,
0025                        struct rxrpc_host_header *hdr,
0026                        struct sk_buff *skb)
0027 {
0028     struct rxrpc_wire_header whdr;
0029     struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
0030     struct sockaddr_rxrpc srx;
0031     struct msghdr msg;
0032     struct kvec iov[2];
0033     size_t len;
0034     int ret;
0035 
0036     _enter("");
0037 
0038     if (rxrpc_extract_addr_from_skb(&srx, skb) < 0)
0039         return;
0040 
0041     msg.msg_name    = &srx.transport;
0042     msg.msg_namelen = srx.transport_len;
0043     msg.msg_control = NULL;
0044     msg.msg_controllen = 0;
0045     msg.msg_flags   = 0;
0046 
0047     whdr.epoch  = htonl(sp->hdr.epoch);
0048     whdr.cid    = htonl(sp->hdr.cid);
0049     whdr.callNumber = htonl(sp->hdr.callNumber);
0050     whdr.seq    = 0;
0051     whdr.serial = 0;
0052     whdr.type   = RXRPC_PACKET_TYPE_VERSION;
0053     whdr.flags  = RXRPC_LAST_PACKET | (~hdr->flags & RXRPC_CLIENT_INITIATED);
0054     whdr.userStatus = 0;
0055     whdr.securityIndex = 0;
0056     whdr._rsvd  = 0;
0057     whdr.serviceId  = htons(sp->hdr.serviceId);
0058 
0059     iov[0].iov_base = &whdr;
0060     iov[0].iov_len  = sizeof(whdr);
0061     iov[1].iov_base = (char *)rxrpc_version_string;
0062     iov[1].iov_len  = sizeof(rxrpc_version_string);
0063 
0064     len = iov[0].iov_len + iov[1].iov_len;
0065 
0066     _proto("Tx VERSION (reply)");
0067 
0068     ret = kernel_sendmsg(local->socket, &msg, iov, 2, len);
0069     if (ret < 0)
0070         trace_rxrpc_tx_fail(local->debug_id, 0, ret,
0071                     rxrpc_tx_point_version_reply);
0072     else
0073         trace_rxrpc_tx_packet(local->debug_id, &whdr,
0074                       rxrpc_tx_point_version_reply);
0075 
0076     _leave("");
0077 }
0078 
0079 /*
0080  * Process event packets targeted at a local endpoint.
0081  */
0082 void rxrpc_process_local_events(struct rxrpc_local *local)
0083 {
0084     struct sk_buff *skb;
0085     char v;
0086 
0087     _enter("");
0088 
0089     skb = skb_dequeue(&local->event_queue);
0090     if (skb) {
0091         struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
0092 
0093         rxrpc_see_skb(skb, rxrpc_skb_seen);
0094         _debug("{%d},{%u}", local->debug_id, sp->hdr.type);
0095 
0096         switch (sp->hdr.type) {
0097         case RXRPC_PACKET_TYPE_VERSION:
0098             if (skb_copy_bits(skb, sizeof(struct rxrpc_wire_header),
0099                       &v, 1) < 0)
0100                 return;
0101             _proto("Rx VERSION { %02x }", v);
0102             if (v == 0)
0103                 rxrpc_send_version_request(local, &sp->hdr, skb);
0104             break;
0105 
0106         default:
0107             /* Just ignore anything we don't understand */
0108             break;
0109         }
0110 
0111         rxrpc_free_skb(skb, rxrpc_skb_freed);
0112     }
0113 
0114     _leave("");
0115 }