Hi Andrey, Thank you for the patch! Yet something to improve:
[auto build test ERROR on bpf-next/master] url: https://github.com/0day-ci/linux/commits/Andrey-Ignatov/bpf-Hooks-for-sys_sendmsg/20180522-065614 base: https://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git master config: x86_64-randconfig-x003-201820 (attached as .config) compiler: gcc-7 (Debian 7.3.0-16) 7.3.0 reproduce: # save the attached .config to linux build tree make ARCH=x86_64 All errors (new ones prefixed by >>): net/ipv4/udp.c: In function 'udp_sendmsg': >> net/ipv4/udp.c:1014:44: error: macro "BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK" >> passed 3 arguments, but takes just 2 (struct sockaddr *)usin, &ipc.addr); ^ >> net/ipv4/udp.c:1013:9: error: 'BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK' >> undeclared (first use in this function); did you mean >> 'BPF_CGROUP_UDP4_SENDMSG'? err = BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BPF_CGROUP_UDP4_SENDMSG net/ipv4/udp.c:1013:9: note: each undeclared identifier is reported only once for each function it appears in -- net/ipv6/udp.c: In function 'udpv6_sendmsg': >> net/ipv6/udp.c:1320:44: error: macro "BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK" >> passed 3 arguments, but takes just 2 (struct sockaddr *)sin6, &fl6.saddr); ^ >> net/ipv6/udp.c:1319:9: error: 'BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK' >> undeclared (first use in this function); did you mean >> 'BPF_CGROUP_UDP6_SENDMSG'? err = BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk, ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ BPF_CGROUP_UDP6_SENDMSG net/ipv6/udp.c:1319:9: note: each undeclared identifier is reported only once for each function it appears in vim +/BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK +1014 net/ipv4/udp.c 898 899 int udp_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) 900 { 901 struct inet_sock *inet = inet_sk(sk); 902 struct udp_sock *up = udp_sk(sk); 903 DECLARE_SOCKADDR(struct sockaddr_in *, usin, msg->msg_name); 904 struct flowi4 fl4_stack; 905 struct flowi4 *fl4; 906 int ulen = len; 907 struct ipcm_cookie ipc; 908 struct rtable *rt = NULL; 909 int free = 0; 910 int connected = 0; 911 __be32 daddr, faddr, saddr; 912 __be16 dport; 913 u8 tos; 914 int err, is_udplite = IS_UDPLITE(sk); 915 int corkreq = up->corkflag || msg->msg_flags&MSG_MORE; 916 int (*getfrag)(void *, char *, int, int, int, struct sk_buff *); 917 struct sk_buff *skb; 918 struct ip_options_data opt_copy; 919 920 if (len > 0xFFFF) 921 return -EMSGSIZE; 922 923 /* 924 * Check the flags. 925 */ 926 927 if (msg->msg_flags & MSG_OOB) /* Mirror BSD error message compatibility */ 928 return -EOPNOTSUPP; 929 930 ipc.opt = NULL; 931 ipc.tx_flags = 0; 932 ipc.ttl = 0; 933 ipc.tos = -1; 934 935 getfrag = is_udplite ? udplite_getfrag : ip_generic_getfrag; 936 937 fl4 = &inet->cork.fl.u.ip4; 938 if (up->pending) { 939 /* 940 * There are pending frames. 941 * The socket lock must be held while it's corked. 942 */ 943 lock_sock(sk); 944 if (likely(up->pending)) { 945 if (unlikely(up->pending != AF_INET)) { 946 release_sock(sk); 947 return -EINVAL; 948 } 949 goto do_append_data; 950 } 951 release_sock(sk); 952 } 953 ulen += sizeof(struct udphdr); 954 955 /* 956 * Get and verify the address. 957 */ 958 if (usin) { 959 if (msg->msg_namelen < sizeof(*usin)) 960 return -EINVAL; 961 if (usin->sin_family != AF_INET) { 962 if (usin->sin_family != AF_UNSPEC) 963 return -EAFNOSUPPORT; 964 } 965 966 daddr = usin->sin_addr.s_addr; 967 dport = usin->sin_port; 968 if (dport == 0) 969 return -EINVAL; 970 } else { 971 if (sk->sk_state != TCP_ESTABLISHED) 972 return -EDESTADDRREQ; 973 daddr = inet->inet_daddr; 974 dport = inet->inet_dport; 975 /* Open fast path for connected socket. 976 Route will not be used, if at least one option is set. 977 */ 978 connected = 1; 979 } 980 981 ipc.sockc.tsflags = sk->sk_tsflags; 982 ipc.addr = inet->inet_saddr; 983 ipc.oif = sk->sk_bound_dev_if; 984 ipc.gso_size = up->gso_size; 985 986 if (msg->msg_controllen) { 987 err = udp_cmsg_send(sk, msg, &ipc.gso_size); 988 if (err > 0) 989 err = ip_cmsg_send(sk, msg, &ipc, 990 sk->sk_family == AF_INET6); 991 if (unlikely(err < 0)) { 992 kfree(ipc.opt); 993 return err; 994 } 995 if (ipc.opt) 996 free = 1; 997 connected = 0; 998 } 999 if (!ipc.opt) { 1000 struct ip_options_rcu *inet_opt; 1001 1002 rcu_read_lock(); 1003 inet_opt = rcu_dereference(inet->inet_opt); 1004 if (inet_opt) { 1005 memcpy(&opt_copy, inet_opt, 1006 sizeof(*inet_opt) + inet_opt->opt.optlen); 1007 ipc.opt = &opt_copy.opt; 1008 } 1009 rcu_read_unlock(); 1010 } 1011 1012 if (!connected) { > 1013 err = BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk, > 1014 (struct sockaddr *)usin, > &ipc.addr); 1015 if (err) 1016 goto out_free; 1017 if (usin) { 1018 if (usin->sin_port == 0) { 1019 /* BPF program set invalid port. Reject it. */ 1020 err = -EINVAL; 1021 goto out_free; 1022 } 1023 daddr = usin->sin_addr.s_addr; 1024 dport = usin->sin_port; 1025 } 1026 } 1027 1028 saddr = ipc.addr; 1029 ipc.addr = faddr = daddr; 1030 1031 sock_tx_timestamp(sk, ipc.sockc.tsflags, &ipc.tx_flags); 1032 1033 if (ipc.opt && ipc.opt->opt.srr) { 1034 if (!daddr) { 1035 err = -EINVAL; 1036 goto out_free; 1037 } 1038 faddr = ipc.opt->opt.faddr; 1039 connected = 0; 1040 } 1041 tos = get_rttos(&ipc, inet); 1042 if (sock_flag(sk, SOCK_LOCALROUTE) || 1043 (msg->msg_flags & MSG_DONTROUTE) || 1044 (ipc.opt && ipc.opt->opt.is_strictroute)) { 1045 tos |= RTO_ONLINK; 1046 connected = 0; 1047 } 1048 1049 if (ipv4_is_multicast(daddr)) { 1050 if (!ipc.oif) 1051 ipc.oif = inet->mc_index; 1052 if (!saddr) 1053 saddr = inet->mc_addr; 1054 connected = 0; 1055 } else if (!ipc.oif) { 1056 ipc.oif = inet->uc_index; 1057 } else if (ipv4_is_lbcast(daddr) && inet->uc_index) { 1058 /* oif is set, packet is to local broadcast and 1059 * and uc_index is set. oif is most likely set 1060 * by sk_bound_dev_if. If uc_index != oif check if the 1061 * oif is an L3 master and uc_index is an L3 slave. 1062 * If so, we want to allow the send using the uc_index. 1063 */ 1064 if (ipc.oif != inet->uc_index && 1065 ipc.oif == l3mdev_master_ifindex_by_index(sock_net(sk), 1066 inet->uc_index)) { 1067 ipc.oif = inet->uc_index; 1068 } 1069 } 1070 1071 if (connected) 1072 rt = (struct rtable *)sk_dst_check(sk, 0); 1073 1074 if (!rt) { 1075 struct net *net = sock_net(sk); 1076 __u8 flow_flags = inet_sk_flowi_flags(sk); 1077 1078 fl4 = &fl4_stack; 1079 1080 flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos, 1081 RT_SCOPE_UNIVERSE, sk->sk_protocol, 1082 flow_flags, 1083 faddr, saddr, dport, inet->inet_sport, 1084 sk->sk_uid); 1085 1086 security_sk_classify_flow(sk, flowi4_to_flowi(fl4)); 1087 rt = ip_route_output_flow(net, fl4, sk); 1088 if (IS_ERR(rt)) { 1089 err = PTR_ERR(rt); 1090 rt = NULL; 1091 if (err == -ENETUNREACH) 1092 IP_INC_STATS(net, IPSTATS_MIB_OUTNOROUTES); 1093 goto out; 1094 } 1095 1096 err = -EACCES; 1097 if ((rt->rt_flags & RTCF_BROADCAST) && 1098 !sock_flag(sk, SOCK_BROADCAST)) 1099 goto out; 1100 if (connected) 1101 sk_dst_set(sk, dst_clone(&rt->dst)); 1102 } 1103 1104 if (msg->msg_flags&MSG_CONFIRM) 1105 goto do_confirm; 1106 back_from_confirm: 1107 1108 saddr = fl4->saddr; 1109 if (!ipc.addr) 1110 daddr = ipc.addr = fl4->daddr; 1111 1112 /* Lockless fast path for the non-corking case. */ 1113 if (!corkreq) { 1114 struct inet_cork cork; 1115 1116 skb = ip_make_skb(sk, fl4, getfrag, msg, ulen, 1117 sizeof(struct udphdr), &ipc, &rt, 1118 &cork, msg->msg_flags); 1119 err = PTR_ERR(skb); 1120 if (!IS_ERR_OR_NULL(skb)) 1121 err = udp_send_skb(skb, fl4, &cork); 1122 goto out; 1123 } 1124 1125 lock_sock(sk); 1126 if (unlikely(up->pending)) { 1127 /* The socket is already corked while preparing it. */ 1128 /* ... which is an evident application bug. --ANK */ 1129 release_sock(sk); 1130 1131 net_dbg_ratelimited("socket already corked\n"); 1132 err = -EINVAL; 1133 goto out; 1134 } 1135 /* 1136 * Now cork the socket to pend data. 1137 */ 1138 fl4 = &inet->cork.fl.u.ip4; 1139 fl4->daddr = daddr; 1140 fl4->saddr = saddr; 1141 fl4->fl4_dport = dport; 1142 fl4->fl4_sport = inet->inet_sport; 1143 up->pending = AF_INET; 1144 1145 do_append_data: 1146 up->len += ulen; 1147 err = ip_append_data(sk, fl4, getfrag, msg, ulen, 1148 sizeof(struct udphdr), &ipc, &rt, 1149 corkreq ? msg->msg_flags|MSG_MORE : msg->msg_flags); 1150 if (err) 1151 udp_flush_pending_frames(sk); 1152 else if (!corkreq) 1153 err = udp_push_pending_frames(sk); 1154 else if (unlikely(skb_queue_empty(&sk->sk_write_queue))) 1155 up->pending = 0; 1156 release_sock(sk); 1157 1158 out: 1159 ip_rt_put(rt); 1160 out_free: 1161 if (free) 1162 kfree(ipc.opt); 1163 if (!err) 1164 return len; 1165 /* 1166 * ENOBUFS = no kernel mem, SOCK_NOSPACE = no sndbuf space. Reporting 1167 * ENOBUFS might not be good (it's not tunable per se), but otherwise 1168 * we don't have a good statistic (IpOutDiscards but it can be too many 1169 * things). We could add another new stat but at least for now that 1170 * seems like overkill. 1171 */ 1172 if (err == -ENOBUFS || test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) { 1173 UDP_INC_STATS(sock_net(sk), 1174 UDP_MIB_SNDBUFERRORS, is_udplite); 1175 } 1176 return err; 1177 1178 do_confirm: 1179 if (msg->msg_flags & MSG_PROBE) 1180 dst_confirm_neigh(&rt->dst, &fl4->daddr); 1181 if (!(msg->msg_flags&MSG_PROBE) || len) 1182 goto back_from_confirm; 1183 err = 0; 1184 goto out; 1185 } 1186 EXPORT_SYMBOL(udp_sendmsg); 1187 --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation
.config.gz
Description: application/gzip