]> git.baikalelectronics.ru Git - kernel.git/commitdiff
net: add a new bind_add method
authorChristoph Hellwig <hch@lst.de>
Fri, 29 May 2020 12:09:42 +0000 (14:09 +0200)
committerDavid S. Miller <davem@davemloft.net>
Fri, 29 May 2020 20:10:39 +0000 (13:10 -0700)
The SCTP protocol allows to bind multiple address to a socket.  That
feature is currently only exposed as a socket option.  Add a bind_add
method struct proto that allows to bind additional addresses, and
switch the dlm code to use the method instead of going through the
socket option from kernel space.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
fs/dlm/lowcomms.c
include/net/sock.h
net/core/sock.c
net/sctp/socket.c

index 9f1c3cdc9d6532dfec05071f68fe40c947ac2b63..3543a8fec9075bd2ba05f5f80dacb204d409ea2c 100644 (file)
@@ -882,6 +882,7 @@ static void writequeue_entry_complete(struct writequeue_entry *e, int completed)
 static int sctp_bind_addrs(struct connection *con, uint16_t port)
 {
        struct sockaddr_storage localaddr;
+       struct sockaddr *addr = (struct sockaddr *)&localaddr;
        int i, addr_len, result = 0;
 
        for (i = 0; i < dlm_local_count; i++) {
@@ -889,13 +890,9 @@ static int sctp_bind_addrs(struct connection *con, uint16_t port)
                make_sockaddr(&localaddr, port, &addr_len);
 
                if (!i)
-                       result = kernel_bind(con->sock,
-                                            (struct sockaddr *)&localaddr,
-                                            addr_len);
+                       result = kernel_bind(con->sock, addr, addr_len);
                else
-                       result = kernel_setsockopt(con->sock, SOL_SCTP,
-                                                  SCTP_SOCKOPT_BINDX_ADD,
-                                                  (char *)&localaddr, addr_len);
+                       result = sock_bind_add(con->sock->sk, addr, addr_len);
 
                if (result < 0) {
                        log_print("Can't bind to %d addr number %d, %d.\n",
index d994daa418ec21765131c3fea8cedb30f229b9f4..6e9f713a78607597db035a3c1eaf50f84ea9379e 100644 (file)
@@ -1156,7 +1156,9 @@ struct proto {
        int                     (*sendpage)(struct sock *sk, struct page *page,
                                        int offset, size_t size, int flags);
        int                     (*bind)(struct sock *sk,
-                                       struct sockaddr *uaddr, int addr_len);
+                                       struct sockaddr *addr, int addr_len);
+       int                     (*bind_add)(struct sock *sk,
+                                       struct sockaddr *addr, int addr_len);
 
        int                     (*backlog_rcv) (struct sock *sk,
                                                struct sk_buff *skb);
@@ -2698,4 +2700,6 @@ void sock_set_reuseaddr(struct sock *sk);
 void sock_set_reuseport(struct sock *sk);
 void sock_set_sndtimeo(struct sock *sk, s64 secs);
 
+int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len);
+
 #endif /* _SOCK_H */
index 2ca3425b519c0e513c3d3e110808ba701866e10a..61ec573221a60195438e9ae27dabf51c6692cf30 100644 (file)
@@ -3712,3 +3712,11 @@ bool sk_busy_loop_end(void *p, unsigned long start_time)
 }
 EXPORT_SYMBOL(sk_busy_loop_end);
 #endif /* CONFIG_NET_RX_BUSY_POLL */
+
+int sock_bind_add(struct sock *sk, struct sockaddr *addr, int addr_len)
+{
+       if (!sk->sk_prot->bind_add)
+               return -EOPNOTSUPP;
+       return sk->sk_prot->bind_add(sk, addr, addr_len);
+}
+EXPORT_SYMBOL(sock_bind_add);
index 6e745ac3c4a596e1b614922d4b890e8e208d63c3..d57e1a002ffc8fe6e484cd5525398fa43d043260 100644 (file)
@@ -1052,6 +1052,18 @@ static int sctp_setsockopt_bindx(struct sock *sk,
        return err;
 }
 
+static int sctp_bind_add(struct sock *sk, struct sockaddr *addrs,
+               int addrlen)
+{
+       int err;
+
+       lock_sock(sk);
+       err = sctp_setsockopt_bindx_kernel(sk, addrs, addrlen,
+                                          SCTP_BINDX_ADD_ADDR);
+       release_sock(sk);
+       return err;
+}
+
 static int sctp_connect_new_asoc(struct sctp_endpoint *ep,
                                 const union sctp_addr *daddr,
                                 const struct sctp_initmsg *init,
@@ -9620,6 +9632,7 @@ struct proto sctp_prot = {
        .sendmsg     =  sctp_sendmsg,
        .recvmsg     =  sctp_recvmsg,
        .bind        =  sctp_bind,
+       .bind_add    =  sctp_bind_add,
        .backlog_rcv =  sctp_backlog_rcv,
        .hash        =  sctp_hash,
        .unhash      =  sctp_unhash,
@@ -9662,6 +9675,7 @@ struct proto sctpv6_prot = {
        .sendmsg        = sctp_sendmsg,
        .recvmsg        = sctp_recvmsg,
        .bind           = sctp_bind,
+       .bind_add       = sctp_bind_add,
        .backlog_rcv    = sctp_backlog_rcv,
        .hash           = sctp_hash,
        .unhash         = sctp_unhash,