From 2f529f9b558ca1c1bd74be7437a84e4711743404 Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Fri, 01 Nov 2024 02:11:33 +0000 Subject: [PATCH] add xenomai --- kernel/net/socket.c | 127 +++++++++++++++++++++++++++++++++++++++++- 1 files changed, 124 insertions(+), 3 deletions(-) diff --git a/kernel/net/socket.c b/kernel/net/socket.c index 938ab3a..ac19dee 100644 --- a/kernel/net/socket.c +++ b/kernel/net/socket.c @@ -141,6 +141,95 @@ #define sock_show_fdinfo NULL #endif +#ifdef CONFIG_NET_OOB + +static inline bool sock_oob_capable(struct socket *sock) +{ + return sock->sk && sock->sk->oob_data; +} + +int __weak sock_oob_attach(struct socket *sock) +{ + return 0; +} + +void __weak sock_oob_detach(struct socket *sock) +{ +} + +int __weak sock_oob_bind(struct socket *sock, struct sockaddr *addr, int len) +{ + return 0; +} + +long __weak sock_inband_ioctl_redirect(struct socket *sock, + unsigned int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +long __weak sock_oob_ioctl(struct file *file, + unsigned int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +ssize_t __weak sock_oob_write(struct file *filp, + const char __user *u_buf, size_t count) +{ + return -EOPNOTSUPP; +} + +ssize_t __weak sock_oob_read(struct file *filp, + char __user *u_buf, size_t count) +{ + return -EOPNOTSUPP; +} + +__poll_t __weak sock_oob_poll(struct file *filp, + struct oob_poll_wait *wait) +{ + return -EOPNOTSUPP; +} + +#define compat_sock_oob_ioctl compat_ptr_oob_ioctl + +#else /* !CONFIG_NET_OOB */ + +static inline bool sock_oob_capable(struct socket *sock) +{ + return false; +} + +static inline int sock_oob_attach(struct socket *sock) +{ + return 0; +} + +static inline void sock_oob_detach(struct socket *sock) +{ +} + +static int sock_oob_bind(struct socket *sock, + struct sockaddr *addr, int len) +{ + return 0; +} + +static inline long sock_inband_ioctl_redirect(struct socket *sock, + unsigned int cmd, unsigned long arg) +{ + return -ENOTTY; +} + +#define sock_oob_ioctl NULL +#define sock_oob_write NULL +#define sock_oob_read NULL +#define sock_oob_poll NULL +#define compat_sock_oob_ioctl NULL + +#endif /* !CONFIG_NET_OOB */ + /* * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear * in the operation structures but are done directly via the socketcall() multiplexor. @@ -153,8 +242,13 @@ .write_iter = sock_write_iter, .poll = sock_poll, .unlocked_ioctl = sock_ioctl, + .oob_ioctl = sock_oob_ioctl, + .oob_write = sock_oob_write, + .oob_read = sock_oob_read, + .oob_poll = sock_oob_poll, #ifdef CONFIG_COMPAT .compat_ioctl = compat_sock_ioctl, + .compat_oob_ioctl = compat_sock_oob_ioctl, #endif .mmap = sock_mmap, .release = sock_close, @@ -427,7 +521,7 @@ static int sock_map_fd(struct socket *sock, int flags) { struct file *newfile; - int fd = get_unused_fd_flags(flags); + int fd = get_unused_fd_flags(flags), ret; if (unlikely(fd < 0)) { sock_release(sock); return fd; @@ -435,6 +529,14 @@ newfile = sock_alloc_file(sock, flags, NULL); if (!IS_ERR(newfile)) { + if (IS_ENABLED(CONFIG_NET_OOB) && (flags & SOCK_OOB)) { + ret = sock_oob_attach(sock); + if (ret < 0) { + put_unused_fd(fd); + sock_release(sock); + return ret; + } + } fd_install(fd, newfile); return fd; } @@ -589,6 +691,9 @@ static void __sock_release(struct socket *sock, struct inode *inode) { + if (sock_oob_capable(sock)) + sock_oob_detach(sock); + if (sock->ops) { struct module *owner = sock->ops->owner; @@ -1185,6 +1290,11 @@ false); break; default: + if (sock_oob_capable(sock)) { + err = sock_inband_ioctl_redirect(sock, cmd, arg); + if (!err || err != -ENOIOCTLCMD) + break; + } err = sock_do_ioctl(net, sock, cmd, arg); break; } @@ -1498,10 +1608,18 @@ BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK); BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK); BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK); + BUILD_BUG_ON(SOCK_OOB & SOCK_TYPE_MASK); flags = type & ~SOCK_TYPE_MASK; - if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) + if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK | SOCK_OOB)) return -EINVAL; + /* + * Not every protocol family supports out-of-band operations, + * however PF_OOB certainly does: force SOCK_OOB in, so that + * sock_oob_attach() runs for this socket. + */ + if (IS_ENABLED(CONFIG_NET_OOB) && family == AF_OOB) + flags |= SOCK_OOB; type &= SOCK_TYPE_MASK; if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) @@ -1511,7 +1629,7 @@ if (retval < 0) return retval; - return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); + return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK | O_OOB)); } SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) @@ -1642,6 +1760,9 @@ err = security_socket_bind(sock, (struct sockaddr *)&address, addrlen); + if (sock_oob_capable(sock) && !err) + err = sock_oob_bind(sock, (struct sockaddr *) + &address, addrlen); if (!err) err = sock->ops->bind(sock, (struct sockaddr *) -- Gitblit v1.6.2