1

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
Dylan Liu
  • 11
  • 2
  • Please post code, errors, sample data or textual output here as plain-text, not as images that can be hard to read, can’t be copy-pasted to help test code or use in answers, and are barrier to those who depend on screen readers. You can edit your question to add the code in the body of your question. For easy formatting use the `{}` button to mark blocks of code, or indent with four spaces for the same effect. The contents of a **screenshot can’t be searched, run as code, or copied and edited to create a solution.** – tadman Jul 28 '20 at 04:43
  • I have revised, thanks for the reminder. – Dylan Liu Jul 28 '20 at 05:37

2 Answers2

0

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()

user3629249
  • 16,402
  • 1
  • 16
  • 17
0

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>
    
sudo_free
  • 1
  • 3