简体   繁体   中英

Netlink : Receiving data multiple times from kernel

I recently encounter a problem when I'm using netlink to transfer many data between userspace and kernelspace. For example, function in userspace releases a request(by sendto) to kernel that it wants some data, and kernelspace replies(by netlink_unicast) to userspace many times. The function "recvfrom" in userspace would stop receiving message at 278 times. Does anyone know how to solve this problem? Here is the sample code below:(test under linux-source-4.15.0)

(Userspace)

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <string.h>
#include <linux/netlink.h>
#include <stdint.h>
#include <unistd.h>
#include <errno.h>

#define NETLINK_TEST    31
#define MSG_LEN            1000
#define MAX_PLOAD        125

typedef struct _user_msg_info
{
    struct nlmsghdr hdr;
    char  msg[MSG_LEN];
} user_msg_info;

int main(int argc, char **argv)
{
    int skfd;
    int ret;
    user_msg_info u_info;
    socklen_t len;
    struct nlmsghdr *nlh = NULL;
    struct sockaddr_nl saddr, daddr;
    char *umsg = "hello netlink!!";

    /* Create NETLINK socket */
    skfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_TEST);
    if(skfd == -1)
    {
        perror("create socket error\n");
        return -1;
    }

    memset(&saddr, 0, sizeof(saddr));
    saddr.nl_family = AF_NETLINK; //AF_NETLINK
    saddr.nl_pid = 100;  // port ID
    saddr.nl_groups = 0;
    if(bind(skfd, (struct sockaddr *)&saddr, sizeof(saddr)) != 0)
    {
        perror("bind() error\n");
        close(skfd);
        return -1;
    }

    memset(&daddr, 0, sizeof(daddr));
    daddr.nl_family = AF_NETLINK;
    daddr.nl_pid = 0; // to kernel
    daddr.nl_groups = 0;

    nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD));
    memset(nlh, 0, sizeof(struct nlmsghdr));
    nlh->nlmsg_len = NLMSG_SPACE(MAX_PLOAD);
    nlh->nlmsg_flags = 0;
    nlh->nlmsg_type = 0;
    nlh->nlmsg_seq = 0;
    nlh->nlmsg_pid = saddr.nl_pid; //self port

    int times  = 400;
    //for(int i=0;i<times;i++){    
        memcpy(NLMSG_DATA(nlh), umsg, strlen(umsg));
        ret = sendto(skfd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&daddr, sizeof(struct sockaddr_nl));
        if(!ret)
        {
            perror("sendto error\n");
            close(skfd);
            exit(-1);
        }
        printf("send kernel:%s\n", umsg);

    //for(int i=0;i<times;i++){
        
        memset(&u_info, 0, sizeof(u_info));
        len = sizeof(struct sockaddr_nl);
    for(int i=0;i<times;i++){
        ret = recvfrom(skfd, &u_info, sizeof(user_msg_info), 0, (struct sockaddr *)&daddr, &len);
        if(!ret)
        {
            perror("recv form kernel error\n");
            close(skfd);
            exit(-1);
        }
        printf("from kernel number[%i]:%s\n", i, u_info.msg);
    }
    printf("end of receiving\n");
    
    close(skfd);

    free((void *)nlh);
    return 0;
}

(Kernel space)

#include <linux/init.h>
#include <linux/module.h>
#include <linux/types.h>
#include <net/sock.h>
#include <linux/netlink.h>

#define NETLINK_TEST     31
#define MSG_LEN            1000
#define USER_PORT        100

MODULE_LICENSE("GPL");
MODULE_AUTHOR("zhangwj");
MODULE_DESCRIPTION("netlink example");

struct sock *nlsk = NULL;
extern struct net init_net;

int send_usrmsg(char *pbuf, uint16_t len)
{
    struct sk_buff *nl_skb;
    struct nlmsghdr *nlh;

    int ret;

    /* Create sk_buff space */
    nl_skb = nlmsg_new(len, GFP_ATOMIC);
    if(!nl_skb)
    {
        printk("netlink alloc failure\n");
        return -1;
    }

    nlh = nlmsg_put(nl_skb, 0, 0, NETLINK_TEST, len, 0);
    if(nlh == NULL)
    {
        printk("nlmsg_put failaure \n");
        nlmsg_free(nl_skb);
        return -1;
    }

    memcpy(nlmsg_data(nlh), pbuf, len);
    ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT);

    return ret;
}

static void netlink_rcv_msg(struct sk_buff *skb)
{
    struct nlmsghdr *nlh = NULL;
    char *umsg = NULL;
    char kmsg[20];

    if(skb->len >= nlmsg_total_size(0))
    {
        nlh = nlmsg_hdr(skb);
        umsg = NLMSG_DATA(nlh);
        if(umsg)
        {
            printk("kernel recv from user: %s\n", umsg);
            int i=0,times=400;
            for(i;i<times;i++){
                sprintf(kmsg,"%d",i);
                send_usrmsg(kmsg,strlen(kmsg));
                int ret = send_usrmsg(kmsg,strlen(kmsg));
                printk("ret[%i]=%i",i,ret);
            }
            // send_usrmsg(kmsg, strlen(kmsg));
        }
    }
}

struct netlink_kernel_cfg cfg = {
        .input  = netlink_rcv_msg, /* set recv callback */
};

int test_netlink_init(void)
{
    /* create netlink socket */
    nlsk = (struct sock *)netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
    if(nlsk == NULL)
    {
        printk("netlink_kernel_create error !\n");
        return -1;
    }
    printk("test_netlink_init\n");

    return 0;
}

void test_netlink_exit(void)
{
    if (nlsk){
        netlink_kernel_release(nlsk); /* release ..*/
        nlsk = NULL;
    }
    printk("test_netlink_exit!\n");
}

module_init(test_netlink_init);
module_exit(test_netlink_exit);

recvfrom() would stop at 278 times, output is as below

send kernel:hello netlink!!
from kernel number[0]:
from kernel number[1]:0
from kernel number[2]:1
from kernel number[3]:2
from kernel number[4]:3
from kernel number[5]:4
from kernel number[6]:5
from kernel number[7]:6
from kernel number[8]:7
from kernel number[9]:8
from kernel number[10]:9
from kernel number[11]:10
from kernel number[12]:11
from kernel number[13]:12
from kernel number[14]:13
from kernel number[15]:14
from kernel number[16]:15
from kernel number[17]:16
from kernel number[18]:17
from kernel number[19]:18
from kernel number[20]:19
from kernel number[21]:20
from kernel number[22]:21
from kernel number[23]:22
from kernel number[24]:23
from kernel number[25]:24
from kernel number[26]:25
from kernel number[27]:26
from kernel number[28]:27
from kernel number[29]:28
from kernel number[30]:29
from kernel number[31]:30
from kernel number[32]:31
from kernel number[33]:32
from kernel number[34]:33
from kernel number[35]:34
from kernel number[36]:35
from kernel number[37]:36
from kernel number[38]:37
from kernel number[39]:38
from kernel number[40]:39
from kernel number[41]:40
from kernel number[42]:41
from kernel number[43]:42
from kernel number[44]:43
from kernel number[45]:44
from kernel number[46]:45
from kernel number[47]:46
from kernel number[48]:47
from kernel number[49]:48
from kernel number[50]:49
from kernel number[51]:50
from kernel number[52]:51
from kernel number[53]:52
from kernel number[54]:53
from kernel number[55]:54
from kernel number[56]:55
from kernel number[57]:56
from kernel number[58]:57
from kernel number[59]:58
from kernel number[60]:59
from kernel number[61]:60
from kernel number[62]:61
from kernel number[63]:62
from kernel number[64]:63
from kernel number[65]:64
from kernel number[66]:65
from kernel number[67]:66
from kernel number[68]:67
from kernel number[69]:68
from kernel number[70]:69
from kernel number[71]:70
from kernel number[72]:71
from kernel number[73]:72
from kernel number[74]:73
from kernel number[75]:74
from kernel number[76]:75
from kernel number[77]:76
from kernel number[78]:77
from kernel number[79]:78
from kernel number[80]:79
from kernel number[81]:80
from kernel number[82]:81
from kernel number[83]:82
from kernel number[84]:83
from kernel number[85]:84
from kernel number[86]:85
from kernel number[87]:86
from kernel number[88]:87
from kernel number[89]:88
from kernel number[90]:89
from kernel number[91]:90
from kernel number[92]:91
from kernel number[93]:92
from kernel number[94]:93
from kernel number[95]:94
from kernel number[96]:95
from kernel number[97]:96
from kernel number[98]:97
from kernel number[99]:98
from kernel number[100]:99
from kernel number[101]:100
from kernel number[102]:101
from kernel number[103]:102
from kernel number[104]:103
from kernel number[105]:104
from kernel number[106]:105
from kernel number[107]:106
from kernel number[108]:107
from kernel number[109]:108
from kernel number[110]:109
from kernel number[111]:110
from kernel number[112]:111
from kernel number[113]:112
from kernel number[114]:113
from kernel number[115]:114
from kernel number[116]:115
from kernel number[117]:116
from kernel number[118]:117
from kernel number[119]:118
from kernel number[120]:119
from kernel number[121]:120
from kernel number[122]:121
from kernel number[123]:122
from kernel number[124]:123
from kernel number[125]:124
from kernel number[126]:125
from kernel number[127]:126
from kernel number[128]:127
from kernel number[129]:128
from kernel number[130]:129
from kernel number[131]:130
from kernel number[132]:131
from kernel number[133]:132
from kernel number[134]:133
from kernel number[135]:134
from kernel number[136]:135
from kernel number[137]:136
from kernel number[138]:137
from kernel number[139]:138
from kernel number[140]:139
from kernel number[141]:140
from kernel number[142]:141
from kernel number[143]:142
from kernel number[144]:143
from kernel number[145]:144
from kernel number[146]:145
from kernel number[147]:146
from kernel number[148]:147
from kernel number[149]:148
from kernel number[150]:149
from kernel number[151]:150
from kernel number[152]:151
from kernel number[153]:152
from kernel number[154]:153
from kernel number[155]:154
from kernel number[156]:155
from kernel number[157]:156
from kernel number[158]:157
from kernel number[159]:158
from kernel number[160]:159
from kernel number[161]:160
from kernel number[162]:161
from kernel number[163]:162
from kernel number[164]:163
from kernel number[165]:164
from kernel number[166]:165
from kernel number[167]:166
from kernel number[168]:167
from kernel number[169]:168
from kernel number[170]:169
from kernel number[171]:170
from kernel number[172]:171
from kernel number[173]:172
from kernel number[174]:173
from kernel number[175]:174
from kernel number[176]:175
from kernel number[177]:176
from kernel number[178]:177
from kernel number[179]:178
from kernel number[180]:179
from kernel number[181]:180
from kernel number[182]:181
from kernel number[183]:182
from kernel number[184]:183
from kernel number[185]:184
from kernel number[186]:185
from kernel number[187]:186
from kernel number[188]:187
from kernel number[189]:188
from kernel number[190]:189
from kernel number[191]:190
from kernel number[192]:191
from kernel number[193]:192
from kernel number[194]:193
from kernel number[195]:194
from kernel number[196]:195
from kernel number[197]:196
from kernel number[198]:197
from kernel number[199]:198
from kernel number[200]:199
from kernel number[201]:200
from kernel number[202]:201
from kernel number[203]:202
from kernel number[204]:203
from kernel number[205]:204
from kernel number[206]:205
from kernel number[207]:206
from kernel number[208]:207
from kernel number[209]:208
from kernel number[210]:209
from kernel number[211]:210
from kernel number[212]:211
from kernel number[213]:212
from kernel number[214]:213
from kernel number[215]:214
from kernel number[216]:215
from kernel number[217]:216
from kernel number[218]:217
from kernel number[219]:218
from kernel number[220]:219
from kernel number[221]:220
from kernel number[222]:221
from kernel number[223]:222
from kernel number[224]:223
from kernel number[225]:224
from kernel number[226]:225
from kernel number[227]:226
from kernel number[228]:227
from kernel number[229]:228
from kernel number[230]:229
from kernel number[231]:230
from kernel number[232]:231
from kernel number[233]:232
from kernel number[234]:233
from kernel number[235]:234
from kernel number[236]:235
from kernel number[237]:236
from kernel number[238]:237
from kernel number[239]:238
from kernel number[240]:239
from kernel number[241]:240
from kernel number[242]:241
from kernel number[243]:242
from kernel number[244]:243
from kernel number[245]:244
from kernel number[246]:245
from kernel number[247]:246
from kernel number[248]:247
from kernel number[249]:248
from kernel number[250]:249
from kernel number[251]:250
from kernel number[252]:251
from kernel number[253]:252
from kernel number[254]:253
from kernel number[255]:254
from kernel number[256]:255
from kernel number[257]:256
from kernel number[258]:257
from kernel number[259]:258
from kernel number[260]:259
from kernel number[261]:260
from kernel number[262]:261
from kernel number[263]:262
from kernel number[264]:263
from kernel number[265]:264
from kernel number[266]:265
from kernel number[267]:266
from kernel number[268]:267
from kernel number[269]:268
from kernel number[270]:269
from kernel number[271]:270
from kernel number[272]:271
from kernel number[273]:272
from kernel number[274]:273
from kernel number[275]:274
from kernel number[276]:275
from kernel number[277]:276
from kernel number[278]:277

In addition, I have added some dubug code in the kernelspace and find that the return value of "netlink_unicast" becomes -11 after 278 times of sending message.

[20134.868249] kernel recv from user: hello netlink!!
[20134.868253] ret[0]=20
[20134.868254] ret[1]=20
[20134.868255] ret[2]=20
[20134.868256] ret[3]=20
[20134.868257] ret[4]=20
[20134.868258] ret[5]=20
[20134.868259] ret[6]=20
[20134.868260] ret[7]=20
[20134.868261] ret[8]=20
[20134.868261] ret[9]=20
[20134.868262] ret[10]=20
[20134.868263] ret[11]=20
[20134.868264] ret[12]=20
[20134.868265] ret[13]=20
[20134.868266] ret[14]=20
[20134.868267] ret[15]=20
[20134.868268] ret[16]=20
[20134.868269] ret[17]=20
[20134.868270] ret[18]=20
[20134.868271] ret[19]=20
[20134.868271] ret[20]=20
[20134.868272] ret[21]=20
[20134.868273] ret[22]=20
[20134.868274] ret[23]=20
[20134.868275] ret[24]=20
[20134.868276] ret[25]=20
[20134.868276] ret[26]=20
[20134.868277] ret[27]=20
[20134.868278] ret[28]=20
[20134.868279] ret[29]=20
[20134.868280] ret[30]=20
[20134.868281] ret[31]=20
[20134.868282] ret[32]=20
[20134.868283] ret[33]=20
[20134.868283] ret[34]=20
[20134.868284] ret[35]=20
[20134.868286] ret[36]=20
[20134.868287] ret[37]=20
[20134.868287] ret[38]=20
[20134.868288] ret[39]=20
[20134.868289] ret[40]=20
[20134.868290] ret[41]=20
[20134.868291] ret[42]=20
[20134.868292] ret[43]=20
[20134.868293] ret[44]=20
[20134.868293] ret[45]=20
[20134.868294] ret[46]=20
[20134.868295] ret[47]=20
[20134.868296] ret[48]=20
[20134.868297] ret[49]=20
[20134.868298] ret[50]=20
[20134.868299] ret[51]=20
[20134.868300] ret[52]=20
[20134.868300] ret[53]=20
[20134.868301] ret[54]=20
[20134.868302] ret[55]=20
[20134.868303] ret[56]=20
[20134.868304] ret[57]=20
[20134.868305] ret[58]=20
[20134.868306] ret[59]=20
[20134.868307] ret[60]=20
[20134.868308] ret[61]=20
[20134.868309] ret[62]=20
[20134.868310] ret[63]=20
[20134.868310] ret[64]=20
[20134.868311] ret[65]=20
[20134.868312] ret[66]=20
[20134.868313] ret[67]=20
[20134.868314] ret[68]=20
[20134.868315] ret[69]=20
[20134.868316] ret[70]=20
[20134.868317] ret[71]=20
[20134.868318] ret[72]=20
[20134.868318] ret[73]=20
[20134.868319] ret[74]=20
[20134.868320] ret[75]=20
[20134.868321] ret[76]=20
[20134.868322] ret[77]=20
[20134.868323] ret[78]=20
[20134.868323] ret[79]=20
[20134.868324] ret[80]=20
[20134.868325] ret[81]=20
[20134.868326] ret[82]=20
[20134.868327] ret[83]=20
[20134.868328] ret[84]=20
[20134.868329] ret[85]=20
[20134.868330] ret[86]=20
[20134.868331] ret[87]=20
[20134.868331] ret[88]=20
[20134.868332] ret[89]=20
[20134.868333] ret[90]=20
[20134.868334] ret[91]=20
[20134.868335] ret[92]=20
[20134.868336] ret[93]=20
[20134.868337] ret[94]=20
[20134.868338] ret[95]=20
[20134.868339] ret[96]=20
[20134.868340] ret[97]=20
[20134.868341] ret[98]=20
[20134.868341] ret[99]=20
[20134.868342] ret[100]=20
[20134.868343] ret[101]=20
[20134.868344] ret[102]=20
[20134.868345] ret[103]=20
[20134.868347] ret[104]=20
[20134.868348] ret[105]=20
[20134.868349] ret[106]=20
[20134.868350] ret[107]=20
[20134.868351] ret[108]=20
[20134.868352] ret[109]=20
[20134.868352] ret[110]=20
[20134.868353] ret[111]=20
[20134.868354] ret[112]=20
[20134.868355] ret[113]=20
[20134.868356] ret[114]=20
[20134.868357] ret[115]=20
[20134.868357] ret[116]=20
[20134.868358] ret[117]=20
[20134.868359] ret[118]=20
[20134.868360] ret[119]=20
[20134.868361] ret[120]=20
[20134.868362] ret[121]=20
[20134.868363] ret[122]=20
[20134.868363] ret[123]=20
[20134.868364] ret[124]=20
[20134.868365] ret[125]=20
[20134.868366] ret[126]=20
[20134.868367] ret[127]=20
[20134.868368] ret[128]=20
[20134.868369] ret[129]=20
[20134.868370] ret[130]=20
[20134.868371] ret[131]=20
[20134.868372] ret[132]=20
[20134.868373] ret[133]=20
[20134.868373] ret[134]=20
[20134.868375] ret[135]=20
[20134.868376] ret[136]=20
[20134.868377] ret[137]=20
[20134.868377] ret[138]=20
[20134.868378] ret[139]=20
[20134.868379] ret[140]=20
[20134.868380] ret[141]=20
[20134.868381] ret[142]=20
[20134.868381] ret[143]=20
[20134.868382] ret[144]=20
[20134.868383] ret[145]=20
[20134.868384] ret[146]=20
[20134.868385] ret[147]=20
[20134.868386] ret[148]=20
[20134.868387] ret[149]=20
[20134.868388] ret[150]=20
[20134.868388] ret[151]=20
[20134.868389] ret[152]=20
[20134.868393] ret[153]=20
[20134.868394] ret[154]=20
[20134.868395] ret[155]=20
[20134.868396] ret[156]=20
[20134.868397] ret[157]=20
[20134.868398] ret[158]=20
[20134.868398] ret[159]=20
[20134.868399] ret[160]=20
[20134.868400] ret[161]=20
[20134.868401] ret[162]=20
[20134.868402] ret[163]=20
[20134.868403] ret[164]=20
[20134.868403] ret[165]=20
[20134.868404] ret[166]=20
[20134.868405] ret[167]=20
[20134.868406] ret[168]=20
[20134.868407] ret[169]=20
[20134.868408] ret[170]=20
[20134.868408] ret[171]=20
[20134.868410] ret[172]=20
[20134.868411] ret[173]=20
[20134.868411] ret[174]=20
[20134.868412] ret[175]=20
[20134.868413] ret[176]=20
[20134.868414] ret[177]=20
[20134.868415] ret[178]=20
[20134.868416] ret[179]=20
[20134.868417] ret[180]=20
[20134.868418] ret[181]=20
[20134.868419] ret[182]=20
[20134.868419] ret[183]=20
[20134.868420] ret[184]=20
[20134.868423] ret[185]=20
[20134.868424] ret[186]=20
[20134.868425] ret[187]=20
[20134.868425] ret[188]=20
[20134.868426] ret[189]=20
[20134.868427] ret[190]=20
[20134.868428] ret[191]=20
[20134.868429] ret[192]=20
[20134.868430] ret[193]=20
[20134.868431] ret[194]=20
[20134.868431] ret[195]=20
[20134.868432] ret[196]=20
[20134.868433] ret[197]=20
[20134.868434] ret[198]=20
[20134.868435] ret[199]=20
[20134.868436] ret[200]=20
[20134.868436] ret[201]=20
[20134.868437] ret[202]=20
[20134.868438] ret[203]=20
[20134.868439] ret[204]=20
[20134.868440] ret[205]=20
[20134.868441] ret[206]=20
[20134.868442] ret[207]=20
[20134.868443] ret[208]=20
[20134.868444] ret[209]=20
[20134.868445] ret[210]=20
[20134.868446] ret[211]=20
[20134.868447] ret[212]=20
[20134.868447] ret[213]=20
[20134.868448] ret[214]=20
[20134.868449] ret[215]=20
[20134.868450] ret[216]=20
[20134.868453] ret[217]=20
[20134.868454] ret[218]=20
[20134.868454] ret[219]=20
[20134.868455] ret[220]=20
[20134.868456] ret[221]=20
[20134.868457] ret[222]=20
[20134.868458] ret[223]=20
[20134.868459] ret[224]=20
[20134.868460] ret[225]=20
[20134.868460] ret[226]=20
[20134.868461] ret[227]=20
[20134.868462] ret[228]=20
[20134.868463] ret[229]=20
[20134.868464] ret[230]=20
[20134.868464] ret[231]=20
[20134.868465] ret[232]=20
[20134.868466] ret[233]=20
[20134.868467] ret[234]=20
[20134.868468] ret[235]=20
[20134.868469] ret[236]=20
[20134.868470] ret[237]=20
[20134.868471] ret[238]=20
[20134.868471] ret[239]=20
[20134.868472] ret[240]=20
[20134.868473] ret[241]=20
[20134.868474] ret[242]=20
[20134.868475] ret[243]=20
[20134.868476] ret[244]=20
[20134.868476] ret[245]=20
[20134.868477] ret[246]=20
[20134.868478] ret[247]=20
[20134.868479] ret[248]=20
[20134.868482] ret[249]=20
[20134.868483] ret[250]=20
[20134.868484] ret[251]=20
[20134.868484] ret[252]=20
[20134.868485] ret[253]=20
[20134.868486] ret[254]=20
[20134.868487] ret[255]=20
[20134.868488] ret[256]=20
[20134.868489] ret[257]=20
[20134.868489] ret[258]=20
[20134.868490] ret[259]=20
[20134.868491] ret[260]=20
[20134.868492] ret[261]=20
[20134.868493] ret[262]=20
[20134.868494] ret[263]=20
[20134.868494] ret[264]=20
[20134.868495] ret[265]=20
[20134.868496] ret[266]=20
[20134.868497] ret[267]=20
[20134.868498] ret[268]=20
[20134.868499] ret[269]=20
[20134.868500] ret[270]=20
[20134.868501] ret[271]=20
[20134.868501] ret[272]=20
[20134.868502] ret[273]=20
[20134.868503] ret[274]=20
[20134.868504] ret[275]=20
[20134.868505] ret[276]=20
[20134.868506] ret[277]=20
[20134.868507] ret[278]=-11
[20134.868508] ret[279]=-11
[20134.868508] ret[280]=-11
[20134.868509] ret[281]=-11
[20134.868510] ret[282]=-11
[20134.868511] ret[283]=-11
[20134.868512] ret[284]=-11
[20134.868513] ret[285]=-11
[20134.868513] ret[286]=-11
[20134.868514] ret[287]=-11
[20134.868515] ret[288]=-11
[20134.868516] ret[289]=-11
[20134.868517] ret[290]=-11
[20134.868517] ret[291]=-11
[20134.868518] ret[292]=-11
[20134.868519] ret[293]=-11
[20134.868520] ret[294]=-11
[20134.868521] ret[295]=-11
[20134.868522] ret[296]=-11
[20134.868522] ret[297]=-11
[20134.868523] ret[298]=-11
[20134.868524] ret[299]=-11
[20134.868525] ret[300]=-11
[20134.868526] ret[301]=-11
[20134.868527] ret[302]=-11
[20134.868527] ret[303]=-11
[20134.868528] ret[304]=-11
[20134.868529] ret[305]=-11
[20134.868530] ret[306]=-11
[20134.868531] ret[307]=-11
[20134.868532] ret[308]=-11
[20134.868532] ret[309]=-11
[20134.868533] ret[310]=-11
[20134.868534] ret[311]=-11
[20134.868535] ret[312]=-11
[20134.868536] ret[313]=-11
[20134.868536] ret[314]=-11
[20134.868537] ret[315]=-11
[20134.868538] ret[316]=-11
[20134.868539] ret[317]=-11
[20134.868540] ret[318]=-11
[20134.868541] ret[319]=-11
[20134.868541] ret[320]=-11
[20134.868542] ret[321]=-11
[20134.868543] ret[322]=-11
[20134.868544] ret[323]=-11
[20134.868545] ret[324]=-11
[20134.868546] ret[325]=-11
[20134.868546] ret[326]=-11
[20134.868547] ret[327]=-11
[20134.868548] ret[328]=-11
[20134.868549] ret[329]=-11
[20134.868550] ret[330]=-11
[20134.868551] ret[331]=-11
[20134.868551] ret[332]=-11
[20134.868552] ret[333]=-11
[20134.868553] ret[334]=-11
[20134.868554] ret[335]=-11
[20134.868555] ret[336]=-11
[20134.868555] ret[337]=-11
[20134.868556] ret[338]=-11
[20134.868557] ret[339]=-11
[20134.868558] ret[340]=-11
[20134.868559] ret[341]=-11
[20134.868560] ret[342]=-11
[20134.868560] ret[343]=-11
[20134.868561] ret[344]=-11
[20134.868562] ret[345]=-11
[20134.868563] ret[346]=-11
[20134.868564] ret[347]=-11
[20134.868565] ret[348]=-11
[20134.868565] ret[349]=-11
[20134.868566] ret[350]=-11
[20134.868567] ret[351]=-11
[20134.868568] ret[352]=-11
[20134.868569] ret[353]=-11
[20134.868570] ret[354]=-11
[20134.868570] ret[355]=-11
[20134.868571] ret[356]=-11
[20134.868572] ret[357]=-11
[20134.868573] ret[358]=-11
[20134.868574] ret[359]=-11
[20134.868574] ret[360]=-11
[20134.868575] ret[361]=-11
[20134.868576] ret[362]=-11
[20134.868577] ret[363]=-11
[20134.868578] ret[364]=-11
[20134.868579] ret[365]=-11
[20134.868579] ret[366]=-11
[20134.868580] ret[367]=-11
[20134.868581] ret[368]=-11
[20134.868582] ret[369]=-11
[20134.868583] ret[370]=-11
[20134.868584] ret[371]=-11
[20134.868584] ret[372]=-11
[20134.868585] ret[373]=-11
[20134.868586] ret[374]=-11
[20134.868587] ret[375]=-11
[20134.868588] ret[376]=-11
[20134.868588] ret[377]=-11
[20134.868589] ret[378]=-11
[20134.868590] ret[379]=-11
[20134.868591] ret[380]=-11
[20134.868592] ret[381]=-11
[20134.868593] ret[382]=-11
[20134.868593] ret[383]=-11
[20134.868594] ret[384]=-11
[20134.868595] ret[385]=-11
[20134.868596] ret[386]=-11
[20134.868597] ret[387]=-11
[20134.868598] ret[388]=-11
[20134.868599] ret[389]=-11
[20134.868600] ret[390]=-11
[20134.868600] ret[391]=-11
[20134.868601] ret[392]=-11
[20134.868602] ret[393]=-11
[20134.868603] ret[394]=-11
[20134.868604] ret[395]=-11
[20134.868605] ret[396]=-11
[20134.868605] ret[397]=-11
[20134.868606] ret[398]=-11
[20134.868607] ret[399]=-11

from the MAN page for recvfrom()

These  calls  return  the  number  of bytes received, or -1 if an error occurred.  
In the event of an error,  errno  is  set  to  indicate  the error.

When a stream socket peer has performed an orderly shutdown, the return value will be 0 (the traditional "end-of-file" return).  

Therefore, the code is not properly checking the returned value from recvfrom()

Update : Solved with a dirty hack: use sock_rfree ( link ) on the skb immediately after you success with nlmsg_unicast . In your case,

if ((ret = netlink_unicast(nlsk, nl_skb, USER_PORT, MSG_DONTWAIT)) >= 0 )
{
  sock_rfree(nl_skb);
}

It will manually decrease the counter, and cause almost no side effect when you userspace receiver fetches the packets fastly. But I do observe some warning traceback generated in dmesg .


Not sure whethere you have solved the problem, but I recently ran into the same situation with the magic number "278".

Just for your reference, I have noticed that it is related to the " receive buffer ":

  • On Ubuntu, the default receiver buffer size is set to the maximum buffer size
    $ cat /proc/sys/net/core/rmem_default # 212992 $ cat /proc/sys/net/core/rmem_max # 212992
  • In kernel, nlmsg_unicast will call netlink_unicast , which will return EAGAIN when unable to attach the skb in netlink_attachskb ( link )
     if ((atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || test_bit(NETLINK_S_CONGESTED, &nlk->state))) { //... return -EAGAIN; //... }
  • In the kernel module, if you check the socket skb->sk , you will see what happens on the actual socket (followed with sample output from my own demo)
     [ 3096.552981] inotify_hook: rmem_alloc: 213504, rcvbuf: 212992 [ 3096.552983] inotify_hook: append_message_cb: message response to 17297 failed: -11. [ 3096.552984] inotify_hook: 278, <the-failed-message-to-dump>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM