@@ -87,41 +87,7 @@ int lkl_if_set_mtu(int ifindex, int mtu)
87
87
88
88
int lkl_if_set_ipv4 (int ifindex , unsigned int addr , unsigned int netmask_len )
89
89
{
90
- struct lkl_ifreq ifr ;
91
- struct lkl_sockaddr_in * sin ;
92
- int err , sock ;
93
-
94
-
95
- sock = lkl_sys_socket (LKL_AF_INET , LKL_SOCK_DGRAM , 0 );
96
- if (sock < 0 )
97
- return sock ;
98
-
99
- err = ifindex_to_name (sock , & ifr , ifindex );
100
- if (err < 0 )
101
- return err ;
102
-
103
- if (netmask_len >= 31 )
104
- return - LKL_EINVAL ;
105
-
106
- sin = (struct lkl_sockaddr_in * )& ifr .lkl_ifr_addr ;
107
- set_sockaddr (sin , addr , 0 );
108
-
109
- err = lkl_sys_ioctl (sock , LKL_SIOCSIFADDR , (long )& ifr );
110
- if (!err ) {
111
- int netmask = (((1 <<netmask_len )- 1 ))<<(32 - netmask_len );
112
-
113
- sin = (struct lkl_sockaddr_in * )& ifr .lkl_ifr_netmask ;
114
- set_sockaddr (sin , htonl (netmask ), 0 );
115
- err = lkl_sys_ioctl (sock , LKL_SIOCSIFNETMASK , (long )& ifr );
116
- if (!err ) {
117
- set_sockaddr (sin , htonl (ntohl (addr )|~netmask ), 0 );
118
- err = lkl_sys_ioctl (sock , LKL_SIOCSIFBRDADDR , (long )& ifr );
119
- }
120
- }
121
-
122
- lkl_sys_close (sock );
123
-
124
- return err ;
90
+ return lkl_if_add_ip (ifindex , LKL_AF_INET , & addr , netmask_len );
125
91
}
126
92
127
93
int lkl_set_ipv4_gateway (unsigned int addr )
@@ -208,7 +174,7 @@ static int parse_rtattr(struct lkl_rtattr *tb[], int max,
208
174
rta = LKL_RTA_NEXT (rta , len );
209
175
}
210
176
if (len )
211
- lkl_printf ( "!!!Deficit %d, rta_len=%d\n" , len ,
177
+ lkl_printf ("!!!Deficit %d, rta_len=%d\n" , len ,
212
178
rta -> rta_len );
213
179
return 0 ;
214
180
}
@@ -244,7 +210,7 @@ static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
244
210
245
211
len -= LKL_NLMSG_LENGTH (sizeof (* ifa ));
246
212
if (len < 0 ) {
247
- lkl_printf ( "BUG: wrong nlmsg len %d\n" , len );
213
+ lkl_printf ("BUG: wrong nlmsg len %d\n" , len );
248
214
return -1 ;
249
215
}
250
216
@@ -267,7 +233,7 @@ static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
267
233
return 1 ;
268
234
}
269
235
if (ifa_flags & LKL_IFA_F_DADFAILED ) {
270
- lkl_printf ( "IPV6 DAD failed.\n" );
236
+ lkl_printf ("IPV6 DAD failed.\n" );
271
237
return -1 ;
272
238
}
273
239
if (!(ifa_flags & LKL_IFA_F_TENTATIVE ))
@@ -300,18 +266,18 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
300
266
if (status < 0 ) {
301
267
if (status == - LKL_EINTR || status == - LKL_EAGAIN )
302
268
continue ;
303
- lkl_printf ( "netlink receive error %s (%d)\n" ,
269
+ lkl_printf ("netlink receive error %s (%d)\n" ,
304
270
lkl_strerror (status ), status );
305
271
if (status == - LKL_ENOBUFS )
306
272
continue ;
307
273
return status ;
308
274
}
309
275
if (status == 0 ) {
310
- lkl_printf ( "EOF on netlink\n" );
276
+ lkl_printf ("EOF on netlink\n" );
311
277
return -1 ;
312
278
}
313
279
if (msg .msg_namelen != sizeof (nladdr )) {
314
- lkl_printf ( "Sender address length == %d\n" ,
280
+ lkl_printf ("Sender address length == %d\n" ,
315
281
msg .msg_namelen );
316
282
return -1 ;
317
283
}
@@ -324,10 +290,10 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
324
290
325
291
if (l < 0 || len > status ) {
326
292
if (msg .msg_flags & LKL_MSG_TRUNC ) {
327
- lkl_printf ( "Truncated message\n" );
293
+ lkl_printf ("Truncated message\n" );
328
294
return -1 ;
329
295
}
330
- lkl_printf ( "!!!malformed message: len=%d\n" ,
296
+ lkl_printf ("!!!malformed message: len=%d\n" ,
331
297
len );
332
298
return -1 ;
333
299
}
@@ -341,17 +307,17 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
341
307
LKL_NLMSG_ALIGN (len ));
342
308
}
343
309
if (msg .msg_flags & LKL_MSG_TRUNC ) {
344
- lkl_printf ( "Message truncated\n" );
310
+ lkl_printf ("Message truncated\n" );
345
311
continue ;
346
312
}
347
313
if (status ) {
348
- lkl_printf ( "!!!Remnant of size %d\n" , status );
314
+ lkl_printf ("!!!Remnant of size %d\n" , status );
349
315
return -1 ;
350
316
}
351
317
}
352
318
}
353
319
354
- static int wait_ipv6 (int ifindex , void * addr )
320
+ int lkl_if_wait_ipv6_dad (int ifindex , void * addr )
355
321
{
356
322
struct addr_filter filter = {.ifindex = ifindex , .addr = addr };
357
323
int fd , ret ;
@@ -383,32 +349,15 @@ static int wait_ipv6(int ifindex, void *addr)
383
349
384
350
int lkl_if_set_ipv6 (int ifindex , void * addr , unsigned int netprefix_len )
385
351
{
386
- struct lkl_in6_ifreq ifr6 ;
387
- int err , sock ;
388
-
389
- if (netprefix_len >= 128 )
390
- return - LKL_EINVAL ;
391
-
392
- sock = lkl_sys_socket (LKL_AF_INET6 , LKL_SOCK_DGRAM , 0 );
393
- if (sock < 0 )
394
- return sock ;
395
-
396
- memcpy (& ifr6 .ifr6_addr .lkl_s6_addr , addr , sizeof (struct lkl_in6_addr ));
397
- ifr6 .ifr6_ifindex = ifindex ;
398
- ifr6 .ifr6_prefixlen = netprefix_len ;
399
-
400
- err = lkl_sys_ioctl (sock , LKL_SIOCSIFADDR , (long )& ifr6 );
401
- lkl_sys_close (sock );
352
+ int err = lkl_if_add_ip (ifindex , LKL_AF_INET6 , addr , netprefix_len );
402
353
if (err )
403
354
return err ;
404
-
405
- err = wait_ipv6 (ifindex , addr );
406
- return err ;
355
+ return lkl_if_wait_ipv6_dad (ifindex , addr );
407
356
}
408
357
409
358
/* returns:
410
359
* 0 - succeed.
411
- * -1 - error.
360
+ * < 0 - error number .
412
361
* 1 - should wait for new msg.
413
362
*/
414
363
static int check_error (struct lkl_sockaddr_nl * nladdr , struct lkl_nlmsghdr * n ,
@@ -427,15 +376,15 @@ static int check_error(struct lkl_sockaddr_nl *nladdr, struct lkl_nlmsghdr *n,
427
376
int l = n -> nlmsg_len - sizeof (* n );
428
377
429
378
if (l < (int )sizeof (struct lkl_nlmsgerr ))
430
- lkl_printf ( "ERROR truncated\n" );
379
+ lkl_printf ("ERROR truncated\n" );
431
380
else if (!err -> error )
432
381
return 0 ;
433
382
434
- lkl_printf ( "RTNETLINK answers: %s\n" ,
383
+ lkl_printf ("RTNETLINK answers: %s\n" ,
435
384
strerror (- err -> error ));
436
- return -1 ;
385
+ return err -> error ;
437
386
}
438
- lkl_printf ( "Unexpected reply!!!\n" );
387
+ lkl_printf ("Unexpected reply!!!\n" );
439
388
return -1 ;
440
389
}
441
390
@@ -466,60 +415,117 @@ static int rtnl_talk(int fd, struct lkl_nlmsghdr *n)
466
415
return status ;
467
416
}
468
417
418
+ static int addattr_l (struct lkl_nlmsghdr * n , unsigned int maxlen ,
419
+ int type , const void * data , int alen )
420
+ {
421
+ int len = LKL_RTA_LENGTH (alen );
422
+ struct lkl_rtattr * rta ;
423
+
424
+ if (LKL_NLMSG_ALIGN (n -> nlmsg_len ) + LKL_RTA_ALIGN (len ) > maxlen ) {
425
+ lkl_printf ("addattr_l ERROR: message exceeded bound of %d\n" ,
426
+ maxlen );
427
+ return -1 ;
428
+ }
429
+ rta = ((struct lkl_rtattr * ) (((void * ) (n )) +
430
+ LKL_NLMSG_ALIGN (n -> nlmsg_len )));
431
+ rta -> rta_type = type ;
432
+ rta -> rta_len = len ;
433
+ memcpy (LKL_RTA_DATA (rta ), data , alen );
434
+ n -> nlmsg_len = LKL_NLMSG_ALIGN (n -> nlmsg_len ) + LKL_RTA_ALIGN (len );
435
+ return 0 ;
436
+ }
437
+
469
438
int lkl_add_neighbor (int ifindex , int af , void * ip , void * mac )
470
439
{
471
440
struct {
472
441
struct lkl_nlmsghdr n ;
473
442
struct lkl_ndmsg r ;
474
443
char buf [1024 ];
475
- } req2 ;
444
+ } req = {
445
+ .n .nlmsg_len = LKL_NLMSG_LENGTH (sizeof (struct lkl_ndmsg )),
446
+ .n .nlmsg_type = LKL_RTM_NEWNEIGH ,
447
+ .n .nlmsg_flags = LKL_NLM_F_REQUEST |
448
+ LKL_NLM_F_CREATE | LKL_NLM_F_REPLACE ,
449
+ .r .ndm_family = af ,
450
+ .r .ndm_ifindex = ifindex ,
451
+ .r .ndm_state = LKL_NUD_PERMANENT ,
452
+
453
+ };
476
454
int err , addr_sz ;
477
- int ndmsglen = LKL_NLMSG_LENGTH (sizeof (struct lkl_ndmsg ));
478
- struct lkl_rtattr * dstattr ;
479
455
int fd ;
480
456
481
457
if (af == LKL_AF_INET )
482
458
addr_sz = 4 ;
483
459
else if (af == LKL_AF_INET6 )
484
460
addr_sz = 16 ;
485
461
else {
486
- lkl_printf ( "Bad address family: %d\n" , af );
462
+ lkl_printf ("Bad address family: %d\n" , af );
487
463
return -1 ;
488
464
}
489
465
490
466
fd = netlink_sock (0 );
491
467
if (fd < 0 )
492
468
return fd ;
493
469
494
- memset (& req2 , 0 , sizeof (req2 ));
495
-
496
470
// create the IP attribute
497
- dstattr = (struct lkl_rtattr * )req2 .buf ;
498
- dstattr -> rta_type = LKL_NDA_DST ;
499
- dstattr -> rta_len = sizeof (struct lkl_rtattr ) + addr_sz ;
500
- memcpy (((char * )dstattr ) + sizeof (struct lkl_rtattr ), ip , addr_sz );
501
- ndmsglen += dstattr -> rta_len ;
471
+ addattr_l (& req .n , sizeof (req ), LKL_NDA_DST , ip , addr_sz );
502
472
503
473
// create the MAC attribute
504
- dstattr = (struct lkl_rtattr * )(req2 .buf + dstattr -> rta_len );
505
- dstattr -> rta_type = LKL_NDA_LLADDR ;
506
- dstattr -> rta_len = sizeof (struct lkl_rtattr ) + 6 ;
507
- memcpy (((char * )dstattr ) + sizeof (struct lkl_rtattr ), mac , 6 );
508
- ndmsglen += dstattr -> rta_len ;
474
+ addattr_l (& req .n , sizeof (req ), LKL_NDA_LLADDR , mac , 6 );
475
+
476
+ err = rtnl_talk (fd , & req .n );
477
+ lkl_sys_close (fd );
478
+ return err ;
479
+ }
480
+
481
+ static int ipaddr_modify (int cmd , int flags , int ifindex , int af , void * addr ,
482
+ unsigned int netprefix_len )
483
+ {
484
+ struct {
485
+ struct lkl_nlmsghdr n ;
486
+ struct lkl_ifaddrmsg ifa ;
487
+ char buf [256 ];
488
+ } req = {
489
+ .n .nlmsg_len = LKL_NLMSG_LENGTH (sizeof (struct lkl_ifaddrmsg )),
490
+ .n .nlmsg_flags = LKL_NLM_F_REQUEST | flags ,
491
+ .n .nlmsg_type = cmd ,
492
+ .ifa .ifa_family = af ,
493
+ .ifa .ifa_prefixlen = netprefix_len ,
494
+ .ifa .ifa_index = ifindex ,
495
+ };
496
+ int err , addr_sz ;
497
+ int fd ;
509
498
510
- // fill in the netlink message header
511
- req2 .n .nlmsg_len = ndmsglen ;
512
- req2 .n .nlmsg_type = LKL_RTM_NEWNEIGH ;
513
- req2 .n .nlmsg_flags =
514
- LKL_NLM_F_REQUEST | LKL_NLM_F_CREATE | LKL_NLM_F_REPLACE ;
499
+ if (af == LKL_AF_INET )
500
+ addr_sz = 4 ;
501
+ else if (af == LKL_AF_INET6 )
502
+ addr_sz = 16 ;
503
+ else {
504
+ lkl_printf ("Bad address family: %d\n" , af );
505
+ return -1 ;
506
+ }
507
+
508
+ fd = netlink_sock (0 );
509
+ if (fd < 0 )
510
+ return fd ;
515
511
516
- // fill in the netlink message NEWNEIGH
517
- req2 .r .ndm_family = af ;
518
- req2 .r .ndm_ifindex = ifindex ;
519
- req2 .r .ndm_state = LKL_NUD_PERMANENT ;
512
+ // create the IP attribute
513
+ addattr_l (& req .n , sizeof (req ), LKL_IFA_LOCAL , addr , addr_sz );
520
514
521
- err = rtnl_talk (fd , & req2 .n );
515
+ err = rtnl_talk (fd , & req .n );
522
516
523
517
lkl_sys_close (fd );
524
518
return err ;
525
519
}
520
+
521
+ int lkl_if_add_ip (int ifindex , int af , void * addr , unsigned int netprefix_len )
522
+ {
523
+ return ipaddr_modify (LKL_RTM_NEWADDR , LKL_NLM_F_CREATE | LKL_NLM_F_EXCL ,
524
+ ifindex , af , addr , netprefix_len );
525
+ }
526
+
527
+ int lkl_if_del_ip (int ifindex , int af , void * addr , unsigned int netprefix_len )
528
+ {
529
+ return ipaddr_modify (LKL_RTM_DELADDR , 0 , ifindex , af ,
530
+ addr , netprefix_len );
531
+ }
0 commit comments