@@ -87,41 +87,7 @@ int lkl_if_set_mtu(int ifindex, int mtu)
8787
8888int lkl_if_set_ipv4 (int ifindex , unsigned int addr , unsigned int netmask_len )
8989{
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 );
12591}
12692
12793int lkl_set_ipv4_gateway (unsigned int addr )
@@ -208,7 +174,7 @@ static int parse_rtattr(struct lkl_rtattr *tb[], int max,
208174 rta = LKL_RTA_NEXT (rta , len );
209175 }
210176 if (len )
211- lkl_printf ( "!!!Deficit %d, rta_len=%d\n" , len ,
177+ lkl_printf ("!!!Deficit %d, rta_len=%d\n" , len ,
212178 rta -> rta_len );
213179 return 0 ;
214180}
@@ -244,7 +210,7 @@ static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
244210
245211 len -= LKL_NLMSG_LENGTH (sizeof (* ifa ));
246212 if (len < 0 ) {
247- lkl_printf ( "BUG: wrong nlmsg len %d\n" , len );
213+ lkl_printf ("BUG: wrong nlmsg len %d\n" , len );
248214 return -1 ;
249215 }
250216
@@ -267,7 +233,7 @@ static int check_ipv6_dad(struct lkl_sockaddr_nl *nladdr,
267233 return 1 ;
268234 }
269235 if (ifa_flags & LKL_IFA_F_DADFAILED ) {
270- lkl_printf ( "IPV6 DAD failed.\n" );
236+ lkl_printf ("IPV6 DAD failed.\n" );
271237 return -1 ;
272238 }
273239 if (!(ifa_flags & LKL_IFA_F_TENTATIVE ))
@@ -300,18 +266,18 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
300266 if (status < 0 ) {
301267 if (status == - LKL_EINTR || status == - LKL_EAGAIN )
302268 continue ;
303- lkl_printf ( "netlink receive error %s (%d)\n" ,
269+ lkl_printf ("netlink receive error %s (%d)\n" ,
304270 lkl_strerror (status ), status );
305271 if (status == - LKL_ENOBUFS )
306272 continue ;
307273 return status ;
308274 }
309275 if (status == 0 ) {
310- lkl_printf ( "EOF on netlink\n" );
276+ lkl_printf ("EOF on netlink\n" );
311277 return -1 ;
312278 }
313279 if (msg .msg_namelen != sizeof (nladdr )) {
314- lkl_printf ( "Sender address length == %d\n" ,
280+ lkl_printf ("Sender address length == %d\n" ,
315281 msg .msg_namelen );
316282 return -1 ;
317283 }
@@ -324,10 +290,10 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
324290
325291 if (l < 0 || len > status ) {
326292 if (msg .msg_flags & LKL_MSG_TRUNC ) {
327- lkl_printf ( "Truncated message\n" );
293+ lkl_printf ("Truncated message\n" );
328294 return -1 ;
329295 }
330- lkl_printf ( "!!!malformed message: len=%d\n" ,
296+ lkl_printf ("!!!malformed message: len=%d\n" ,
331297 len );
332298 return -1 ;
333299 }
@@ -341,17 +307,17 @@ static int rtnl_listen(int fd, int (*handler)(struct lkl_sockaddr_nl *nladdr,
341307 LKL_NLMSG_ALIGN (len ));
342308 }
343309 if (msg .msg_flags & LKL_MSG_TRUNC ) {
344- lkl_printf ( "Message truncated\n" );
310+ lkl_printf ("Message truncated\n" );
345311 continue ;
346312 }
347313 if (status ) {
348- lkl_printf ( "!!!Remnant of size %d\n" , status );
314+ lkl_printf ("!!!Remnant of size %d\n" , status );
349315 return -1 ;
350316 }
351317 }
352318}
353319
354- static int wait_ipv6 (int ifindex , void * addr )
320+ int lkl_if_wait_ipv6_dad (int ifindex , void * addr )
355321{
356322 struct addr_filter filter = {.ifindex = ifindex , .addr = addr };
357323 int fd , ret ;
@@ -383,32 +349,15 @@ static int wait_ipv6(int ifindex, void *addr)
383349
384350int lkl_if_set_ipv6 (int ifindex , void * addr , unsigned int netprefix_len )
385351{
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 );
402353 if (err )
403354 return err ;
404-
405- err = wait_ipv6 (ifindex , addr );
406- return err ;
355+ return lkl_if_wait_ipv6_dad (ifindex , addr );
407356}
408357
409358/* returns:
410359 * 0 - succeed.
411- * -1 - error.
360+ * < 0 - error number .
412361 * 1 - should wait for new msg.
413362 */
414363static 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,
427376 int l = n -> nlmsg_len - sizeof (* n );
428377
429378 if (l < (int )sizeof (struct lkl_nlmsgerr ))
430- lkl_printf ( "ERROR truncated\n" );
379+ lkl_printf ("ERROR truncated\n" );
431380 else if (!err -> error )
432381 return 0 ;
433382
434- lkl_printf ( "RTNETLINK answers: %s\n" ,
383+ lkl_printf ("RTNETLINK answers: %s\n" ,
435384 strerror (- err -> error ));
436- return -1 ;
385+ return err -> error ;
437386 }
438- lkl_printf ( "Unexpected reply!!!\n" );
387+ lkl_printf ("Unexpected reply!!!\n" );
439388 return -1 ;
440389}
441390
@@ -466,60 +415,117 @@ static int rtnl_talk(int fd, struct lkl_nlmsghdr *n)
466415 return status ;
467416}
468417
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+
469438int lkl_add_neighbor (int ifindex , int af , void * ip , void * mac )
470439{
471440 struct {
472441 struct lkl_nlmsghdr n ;
473442 struct lkl_ndmsg r ;
474443 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+ };
476454 int err , addr_sz ;
477- int ndmsglen = LKL_NLMSG_LENGTH (sizeof (struct lkl_ndmsg ));
478- struct lkl_rtattr * dstattr ;
479455 int fd ;
480456
481457 if (af == LKL_AF_INET )
482458 addr_sz = 4 ;
483459 else if (af == LKL_AF_INET6 )
484460 addr_sz = 16 ;
485461 else {
486- lkl_printf ( "Bad address family: %d\n" , af );
462+ lkl_printf ("Bad address family: %d\n" , af );
487463 return -1 ;
488464 }
489465
490466 fd = netlink_sock (0 );
491467 if (fd < 0 )
492468 return fd ;
493469
494- memset (& req2 , 0 , sizeof (req2 ));
495-
496470 // 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 );
502472
503473 // 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 ;
509498
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 ;
515511
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 );
520514
521- err = rtnl_talk (fd , & req2 .n );
515+ err = rtnl_talk (fd , & req .n );
522516
523517 lkl_sys_close (fd );
524518 return err ;
525519}
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