mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-20 21:51:05 +00:00
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Conflicts: net/ipv4/arp.c The net/ipv4/arp.c conflict was one commit adding a new local variable while another commit was deleting one. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
commit
4963ed48f2
1105 changed files with 12650 additions and 7326 deletions
|
@ -125,6 +125,24 @@ static inline u32 netlink_group_mask(u32 group)
|
|||
return group ? 1 << (group - 1) : 0;
|
||||
}
|
||||
|
||||
static struct sk_buff *netlink_to_full_skb(const struct sk_buff *skb,
|
||||
gfp_t gfp_mask)
|
||||
{
|
||||
unsigned int len = skb_end_offset(skb);
|
||||
struct sk_buff *new;
|
||||
|
||||
new = alloc_skb(len, gfp_mask);
|
||||
if (new == NULL)
|
||||
return NULL;
|
||||
|
||||
NETLINK_CB(new).portid = NETLINK_CB(skb).portid;
|
||||
NETLINK_CB(new).dst_group = NETLINK_CB(skb).dst_group;
|
||||
NETLINK_CB(new).creds = NETLINK_CB(skb).creds;
|
||||
|
||||
memcpy(skb_put(new, len), skb->data, len);
|
||||
return new;
|
||||
}
|
||||
|
||||
int netlink_add_tap(struct netlink_tap *nt)
|
||||
{
|
||||
if (unlikely(nt->dev->type != ARPHRD_NETLINK))
|
||||
|
@ -206,7 +224,11 @@ static int __netlink_deliver_tap_skb(struct sk_buff *skb,
|
|||
int ret = -ENOMEM;
|
||||
|
||||
dev_hold(dev);
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
|
||||
if (netlink_skb_is_mmaped(skb) || is_vmalloc_addr(skb->head))
|
||||
nskb = netlink_to_full_skb(skb, GFP_ATOMIC);
|
||||
else
|
||||
nskb = skb_clone(skb, GFP_ATOMIC);
|
||||
if (nskb) {
|
||||
nskb->dev = dev;
|
||||
nskb->protocol = htons((u16) sk->sk_protocol);
|
||||
|
@ -279,11 +301,6 @@ static void netlink_rcv_wake(struct sock *sk)
|
|||
}
|
||||
|
||||
#ifdef CONFIG_NETLINK_MMAP
|
||||
static bool netlink_skb_is_mmaped(const struct sk_buff *skb)
|
||||
{
|
||||
return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
|
||||
}
|
||||
|
||||
static bool netlink_rx_is_mmaped(struct sock *sk)
|
||||
{
|
||||
return nlk_sk(sk)->rx_ring.pg_vec != NULL;
|
||||
|
@ -846,7 +863,6 @@ static void netlink_ring_set_copied(struct sock *sk, struct sk_buff *skb)
|
|||
}
|
||||
|
||||
#else /* CONFIG_NETLINK_MMAP */
|
||||
#define netlink_skb_is_mmaped(skb) false
|
||||
#define netlink_rx_is_mmaped(sk) false
|
||||
#define netlink_tx_is_mmaped(sk) false
|
||||
#define netlink_mmap sock_no_mmap
|
||||
|
@ -1094,8 +1110,8 @@ static int netlink_insert(struct sock *sk, u32 portid)
|
|||
|
||||
lock_sock(sk);
|
||||
|
||||
err = -EBUSY;
|
||||
if (nlk_sk(sk)->portid)
|
||||
err = nlk_sk(sk)->portid == portid ? 0 : -EBUSY;
|
||||
if (nlk_sk(sk)->bound)
|
||||
goto err;
|
||||
|
||||
err = -ENOMEM;
|
||||
|
@ -1115,10 +1131,14 @@ static int netlink_insert(struct sock *sk, u32 portid)
|
|||
err = -EOVERFLOW;
|
||||
if (err == -EEXIST)
|
||||
err = -EADDRINUSE;
|
||||
nlk_sk(sk)->portid = 0;
|
||||
sock_put(sk);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We need to ensure that the socket is hashed and visible. */
|
||||
smp_wmb();
|
||||
nlk_sk(sk)->bound = portid;
|
||||
|
||||
err:
|
||||
release_sock(sk);
|
||||
return err;
|
||||
|
@ -1503,6 +1523,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
|||
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
|
||||
int err;
|
||||
long unsigned int groups = nladdr->nl_groups;
|
||||
bool bound;
|
||||
|
||||
if (addr_len < sizeof(struct sockaddr_nl))
|
||||
return -EINVAL;
|
||||
|
@ -1519,9 +1540,14 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
|||
return err;
|
||||
}
|
||||
|
||||
if (nlk->portid)
|
||||
bound = nlk->bound;
|
||||
if (bound) {
|
||||
/* Ensure nlk->portid is up-to-date. */
|
||||
smp_rmb();
|
||||
|
||||
if (nladdr->nl_pid != nlk->portid)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (nlk->netlink_bind && groups) {
|
||||
int group;
|
||||
|
@ -1537,7 +1563,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
|
|||
}
|
||||
}
|
||||
|
||||
if (!nlk->portid) {
|
||||
/* No need for barriers here as we return to user-space without
|
||||
* using any of the bound attributes.
|
||||
*/
|
||||
if (!bound) {
|
||||
err = nladdr->nl_pid ?
|
||||
netlink_insert(sk, nladdr->nl_pid) :
|
||||
netlink_autobind(sock);
|
||||
|
@ -1585,7 +1614,10 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr,
|
|||
!netlink_allowed(sock, NL_CFG_F_NONROOT_SEND))
|
||||
return -EPERM;
|
||||
|
||||
if (!nlk->portid)
|
||||
/* No need for barriers here as we return to user-space without
|
||||
* using any of the bound attributes.
|
||||
*/
|
||||
if (!nlk->bound)
|
||||
err = netlink_autobind(sock);
|
||||
|
||||
if (err == 0) {
|
||||
|
@ -2426,10 +2458,13 @@ static int netlink_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
|
|||
dst_group = nlk->dst_group;
|
||||
}
|
||||
|
||||
if (!nlk->portid) {
|
||||
if (!nlk->bound) {
|
||||
err = netlink_autobind(sock);
|
||||
if (err)
|
||||
goto out;
|
||||
} else {
|
||||
/* Ensure nlk is hashed and visible. */
|
||||
smp_rmb();
|
||||
}
|
||||
|
||||
/* It's a really convoluted way for userland to ask for mmaped
|
||||
|
|
|
@ -35,6 +35,7 @@ struct netlink_sock {
|
|||
unsigned long state;
|
||||
size_t max_recvmsg_len;
|
||||
wait_queue_head_t wait;
|
||||
bool bound;
|
||||
bool cb_running;
|
||||
struct netlink_callback cb;
|
||||
struct mutex *cb_mutex;
|
||||
|
@ -59,6 +60,15 @@ static inline struct netlink_sock *nlk_sk(struct sock *sk)
|
|||
return container_of(sk, struct netlink_sock, sk);
|
||||
}
|
||||
|
||||
static inline bool netlink_skb_is_mmaped(const struct sk_buff *skb)
|
||||
{
|
||||
#ifdef CONFIG_NETLINK_MMAP
|
||||
return NETLINK_CB(skb).flags & NETLINK_SKB_MMAPED;
|
||||
#else
|
||||
return false;
|
||||
#endif /* CONFIG_NETLINK_MMAP */
|
||||
}
|
||||
|
||||
struct netlink_table {
|
||||
struct rhashtable hash;
|
||||
struct hlist_head mc_list;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue