Отбрасывание пакетов UDP

Если вы знаете верхний предел файлов, то:

for i in {000..074}
  do
  if [ -f "$i.mat" ]
  then
    echo "$i.mat exists"
  else
    echo "$i.mat doesn't exists"
  fi
done

Вы можете изменить команды echoпо своему желанию.

0
29.09.2020, 16:34
1 ответ

В Linux 5.4.66 псевдофайл -/proc/net/udpгенерируется функцией изnet/ipv4/udp.c:

int udp4_seq_show(struct seq_file *seq, void *v)
{
        seq_setwidth(seq, 127);
        if (v == SEQ_START_TOKEN)
                seq_puts(seq, "  sl  local_address rem_address   st tx_queue "
                           "rx_queue tr tm->when retrnsmt   uid  timeout "
                           "inode ref pointer drops");
        else {
                struct udp_iter_state *state = seq->private;

                udp4_format_sock(v, seq, state->bucket);
        }
        seq_pad(seq, '\n');
        return 0;
}

Это вызывает udp4_format_sock()в том же файле:

static void udp4_format_sock(struct sock *sp, struct seq_file *f,
                int bucket)
{
        struct inet_sock *inet = inet_sk(sp);
        __be32 dest = inet->inet_daddr;
        __be32 src  = inet->inet_rcv_saddr;
        __u16 destp       = ntohs(inet->inet_dport);
        __u16 srcp        = ntohs(inet->inet_sport);

        seq_printf(f, "%5d: %08X:%04X %08X:%04X"
                " %02X %08X:%08X %02X:%08lX %08X %5u %8d %lu %d %pK %u",
                bucket, src, srcp, dest, destp, sp->sk_state,
                sk_wmem_alloc_get(sp),
                udp_rqueue_get(sp),
                0, 0L, 0,
                from_kuid_munged(seq_user_ns(f), sock_i_uid(sp)),
                0, sock_i_ino(sp),
                refcount_read(&sp->sk_refcnt), sp,
                atomic_read(&sp->sk_drops));
}

Обратите внимание, что значение поля dropsберется из atomic_read(&sp->sk_drops). Это значение увеличивается с помощью atomic_inc(&sk->sk_drops)в нескольких местах.

  1. Очередь приема заполнена

    int __udp_enqueue_schedule_skb(struct sock *sk, struct sk_buff *skb)
    {
            ...
            /* try to avoid the costly atomic add/sub pair when the receive
             * queue is full; always allow at least a packet
             */
            rmem = atomic_read(&sk->sk_rmem_alloc);
            if (rmem > sk->sk_rcvbuf)
                     goto drop;
          ...
    drop:
            atomic_inc(&sk->sk_drops);
    
  2. Плохие кадры контрольной суммы

    static struct sk_buff *__first_packet_length(struct sock *sk,
                                                 struct sk_buff_head *rcvq,
                                                 int *total)
    {
            struct sk_buff *skb;
    
            while ((skb = skb_peek(rcvq)) != NULL) {
                    if (udp_lib_checksum_complete(skb)) {
                           ...
                            atomic_inc(&sk->sk_drops);
    
  3. Ошибка чтения

    int udp_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, int noblock,
                    int flags, int *addr_len)
    {
           ...
            if (checksum_valid || udp_skb_csum_unnecessary(skb)) {
                    if (udp_skb_is_linear(skb))
                            err = copy_linear_skb(skb, copied, off, &msg->msg_iter);
                    else
                            err = skb_copy_datagram_msg(skb, off, msg, copied);
            } else {
                    err = skb_copy_and_csum_datagram_msg(skb, off, msg);
    
                    if (err == -EINVAL)
                            goto csum_copy_err;
            }
    
            if (unlikely(err)) {
                    if (!peeking) {
                            atomic_inc(&sk->sk_drops);
    
  4. Сбои при приеме

    static int udp_queue_rcv_one_skb(struct sock *sk, struct sk_buff *skb)
    {
           ...
    drop:
           ...
            atomic_inc(&sk->sk_drops);
    
  5. Сбои при многоадресной обработке при попытке клонирования сообщения

    static int __udp4_lib_mcast_deliver(struct net *net, struct sk_buff *skb,
                                        struct udphdr  *uh,
                                        __be32 saddr, __be32 daddr,
                                        struct udp_table *udptable,
                                        int proto)
    {
           ...
            sk_for_each_entry_offset_rcu(sk, node, &hslot->head, offset) {
                   ...
                    nskb = skb_clone(skb, GFP_ATOMIC);
    
                    if (unlikely(!nskb)) {
                            atomic_inc(&sk->sk_drops);
    
    
3
18.03.2021, 23:01

Теги

Похожие вопросы