Merge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next
[sfrench/cifs-2.6.git] / net / ipv6 / af_inet6.c
index 8e9c3e9ea36e34fefe5e842f7b81a274a69e4e17..1fb75f01756c0f725345a93e4bd954c5c3327023 100644 (file)
@@ -295,7 +295,8 @@ static int __inet6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len,
                return -EINVAL;
 
        snum = ntohs(addr->sin6_port);
-       if (snum && inet_port_requires_bind_service(net, snum) &&
+       if (!(flags & BIND_NO_CAP_NET_BIND_SERVICE) &&
+           snum && inet_port_requires_bind_service(net, snum) &&
            !ns_capable(net->user_ns, CAP_NET_BIND_SERVICE))
                return -EACCES;
 
@@ -439,6 +440,7 @@ out_unlock:
 int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
 {
        struct sock *sk = sock->sk;
+       u32 flags = BIND_WITH_LOCK;
        int err = 0;
 
        /* If the socket has its own bind function then use it. */
@@ -451,11 +453,12 @@ int inet6_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
        /* BPF prog is run before any checks are done so that if the prog
         * changes context in a wrong way it will be caught.
         */
-       err = BPF_CGROUP_RUN_PROG_INET6_BIND_LOCK(sk, uaddr);
+       err = BPF_CGROUP_RUN_PROG_INET_BIND_LOCK(sk, uaddr,
+                                                BPF_CGROUP_INET6_BIND, &flags);
        if (err)
                return err;
 
-       return __inet6_bind(sk, uaddr, addr_len, BIND_WITH_LOCK);
+       return __inet6_bind(sk, uaddr, addr_len, flags);
 }
 EXPORT_SYMBOL(inet6_bind);
 
@@ -527,18 +530,19 @@ int inet6_getname(struct socket *sock, struct sockaddr *uaddr,
                sin->sin6_addr = sk->sk_v6_daddr;
                if (np->sndflow)
                        sin->sin6_flowinfo = np->flow_label;
+               BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin,
+                                           BPF_CGROUP_INET6_GETPEERNAME,
+                                           NULL);
        } else {
                if (ipv6_addr_any(&sk->sk_v6_rcv_saddr))
                        sin->sin6_addr = np->saddr;
                else
                        sin->sin6_addr = sk->sk_v6_rcv_saddr;
                sin->sin6_port = inet->inet_sport;
-       }
-       if (cgroup_bpf_enabled)
                BPF_CGROUP_RUN_SA_PROG_LOCK(sk, (struct sockaddr *)sin,
-                                           peer ? BPF_CGROUP_INET6_GETPEERNAME :
-                                                  BPF_CGROUP_INET6_GETSOCKNAME,
+                                           BPF_CGROUP_INET6_GETSOCKNAME,
                                            NULL);
+       }
        sin->sin6_scope_id = ipv6_iface_scope_id(&sin->sin6_addr,
                                                 sk->sk_bound_dev_if);
        return sizeof(*sin);
@@ -954,6 +958,7 @@ static int __net_init inet6_net_init(struct net *net)
        net->ipv6.sysctl.max_hbh_opts_cnt = IP6_DEFAULT_MAX_HBH_OPTS_CNT;
        net->ipv6.sysctl.max_dst_opts_len = IP6_DEFAULT_MAX_DST_OPTS_LEN;
        net->ipv6.sysctl.max_hbh_opts_len = IP6_DEFAULT_MAX_HBH_OPTS_LEN;
+       net->ipv6.sysctl.fib_notify_on_flag_change = 0;
        atomic_set(&net->ipv6.fib6_sernum, 1);
 
        err = ipv6_init_mibs(net);