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: i386-randconfig-s1-201820 (attached as .config)
compiler: gcc-6 (Debian 6.4.0-9) 6.4.0 20171026
reproduce:
        # save the attached .config to linux build tree
        make ARCH=i386 

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)
      err = BPF_CGROUP_RUN_PROG_UDP4_SENDMSG_LOCK(sk,
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   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)
      err = BPF_CGROUP_RUN_PROG_UDP6_SENDMSG_LOCK(sk,
            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   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 +1013 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

Attachment: .config.gz
Description: application/gzip

Reply via email to