2 * Connection oriented routing
3 * Copyright (C) 2007-2021 Michael Blizek
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 #include <linux/net.h>
23 #include <asm/uaccess.h>
27 struct proto cor_proto
= {
29 .obj_size
= sizeof(struct cor_sock
),
33 void cor_free_sock(struct kref
*ref
)
35 struct cor_sock
*cs
= container_of(ref
, struct cor_sock
, ref
);
37 if (cs
->type
== CS_TYPE_CONN_MANAGED
) {
38 if (cs
->data
.conn_managed
.rcv_buf
!= 0) {
39 kfree(cs
->data
.conn_managed
.rcv_buf
);
40 cs
->data
.conn_managed
.rcv_buf
= 0;
43 if (cs
->data
.conn_managed
.snd_buf
!= 0) {
44 kfree(cs
->data
.conn_managed
.snd_buf
);
45 cs
->data
.conn_managed
.snd_buf
= 0;
50 sock_put((struct sock
*) cs
);
53 int cor_socket_setsockopt_tos(struct socket
*sock
,
54 char __user
*optval
, unsigned int optlen
)
56 struct cor_sock
*cs
= (struct cor_sock
*) sock
->sk
;
61 if (unlikely(optlen
!= 4))
64 notread
= copy_from_user((char *) &tos
, optval
, 4);
65 if (unlikely(notread
!= 0))
68 if (unlikely(tos
!= COR_TOS_DEFAULT
&& tos
!= COR_TOS_LOW_LATENCY
&&
69 tos
!= COR_TOS_HIGH_LATENCY
))
72 mutex_lock(&(cs
->lock
));
73 cs
->is_highlatency
= (tos
== COR_TOS_HIGH_LATENCY
);
74 mutex_unlock(&(cs
->lock
));
79 int cor_socket_socketpair(struct socket
*sock1
, struct socket
*sock2
)
84 int cor_socket_getname(struct socket
*sock
, struct sockaddr
*addr
, int peer
)
89 int cor_socket_mmap(struct file
*file
, struct socket
*sock
,
90 struct vm_area_struct
*vma
)
95 int _cor_createsock(struct net
*net
, struct socket
*sock
, int protocol
,
98 struct cor_sock
*cs
= (struct cor_sock
*) sk_alloc(net
, PF_COR
,
99 GFP_KERNEL
, &cor_proto
, kern
);
100 if (unlikely(cs
== 0))
103 BUILD_BUG_ON(offsetof(struct cor_sock
, sk
) != 0);
105 sock_init_data(sock
, &(cs
->sk
));
106 cs
->sk
.sk_protocol
= protocol
;
108 memset(((char *)cs
) + sizeof(struct sock
), 0, sizeof(struct cor_sock
) -
109 sizeof(struct sock
));
111 cs
->type
= CS_TYPE_UNCONNECTED
;
112 mutex_init(&(cs
->lock
));
113 kref_init(&(cs
->ref
));
115 INIT_WORK(&(cs
->readfromconn_work
), cor_mngdsocket_readfromconn_wq
);
116 atomic_set(&(cs
->readfromconn_work_scheduled
), 0);
118 atomic_set(&(cs
->ready_to_read
), 0);
119 atomic_set(&(cs
->ready_to_write
), 0);
120 atomic_set(&(cs
->ready_to_accept
), 0);
122 sock
->state
= SS_UNCONNECTED
;
123 sock
->sk
= &(cs
->sk
);
128 int cor_createsock(struct net
*net
, struct socket
*sock
, int protocol
, int kern
)
130 if (sock
->type
== SOCK_RAW
) {
131 if (unlikely(kern
== 0 && capable(CAP_NET_ADMIN
) == 0))
134 if (likely(protocol
== PROTO_COR_RAW
)) {
135 return cor_create_raw_sock(net
, sock
, protocol
, kern
);
136 } else if (protocol
== PROTO_COR_RDEAMON
) {
137 return cor_create_rdaemon_sock(net
, sock
, protocol
,
140 return -EPROTONOSUPPORT
;
142 return -EPROTONOSUPPORT
;
143 } else if (sock
->type
== SOCK_STREAM
) {
144 if (unlikely(protocol
!= 0)) {
145 return -EPROTONOSUPPORT
;
147 return cor_create_managed_sock(net
, sock
, protocol
, kern
);
149 return -EPROTONOSUPPORT
;
153 static struct net_proto_family cor_net_proto_family __read_mostly
= {
155 .create
= cor_createsock
,
159 int __init
cor_sock_init2(void)
163 rc
= proto_register(&cor_proto
, 1);
167 rc
= sock_register(&cor_net_proto_family
);
174 void __exit
cor_sock_exit1(void)
176 proto_unregister(&cor_proto
);
177 sock_unregister(PF_COR
);
180 MODULE_LICENSE("GPL");