6565 _nest->rta_len = (unsigned short)((void *)sitnl_nlmsg_tail(_msg) - (void *)_nest); \
6666 }
6767
68+ int netns_fd ;
69+
6870/* This function was originally implemented as a macro, but compiling with
6971 * gcc and -O3 was getting confused about the math and thus raising
7072 * security warnings on subsequent memcpy() calls.
@@ -529,6 +531,114 @@ sitnl_route_save(struct nlmsghdr *n, void *arg)
529531 return 0 ;
530532}
531533
534+ static int
535+ sitnl_link_get_ifindex (struct nlmsghdr * n , void * arg )
536+ {
537+ struct sitnl_link_req * res = arg ;
538+ struct ifinfomsg * ifi ;
539+
540+ if (n -> nlmsg_type != RTM_NEWLINK )
541+ return 1 ;
542+
543+ ifi = NLMSG_DATA (n );
544+ res -> i = * ifi ;
545+
546+ return 0 ;
547+ }
548+
549+ static int
550+ get_ifindex_in_netns (const char * ifname , int netnsid )
551+ {
552+ struct sitnl_link_req req ;
553+ struct sitnl_link_req res ;
554+ int ret ;
555+
556+ CLEAR (req );
557+ CLEAR (res );
558+
559+ req .n .nlmsg_len = NLMSG_LENGTH (sizeof (req .i ));
560+ req .n .nlmsg_type = RTM_GETLINK ;
561+ req .n .nlmsg_flags = NLM_F_REQUEST ;
562+
563+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_TARGET_NETNSID , & netnsid , sizeof (int ));
564+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_IFNAME , ifname , strlen (ifname ) + 1 );
565+
566+ ret = sitnl_send (& req .n , 0 , 0 , sitnl_link_get_ifindex , & res );
567+
568+ if (ret < 0 )
569+ {
570+ goto err ;
571+ }
572+
573+ return res .i .ifi_index ;
574+
575+ err :
576+ return ret ;
577+ }
578+
579+ int
580+ openvpn_if_nametoindex (const char * ifname , int netnsid )
581+ {
582+ if (netnsid < 0 )
583+ {
584+ return if_nametoindex (ifname );
585+ }
586+
587+ return get_ifindex_in_netns (ifname , netnsid );
588+ }
589+
590+ int
591+ net_iface_move_netns (const char * iface ,
592+ const char * netns_path )
593+ {
594+ struct sitnl_link_req req = {};
595+ int ret = -1 ;
596+ int ifindex ;
597+ int netns_fd ;
598+
599+ ASSERT (iface );
600+ ASSERT (netns_path );
601+
602+ ifindex = if_nametoindex (iface );
603+ if (ifindex == 0 )
604+ {
605+ msg (M_ERR , "%s: if_nametoindex(%s) failed" , __func__ , iface );
606+ goto err ;
607+ }
608+
609+ netns_fd = open (netns_path , O_RDONLY );
610+ if (netns_fd < 0 )
611+ {
612+ msg (M_ERR , "%s: open(%s) failed: %s" ,
613+ __func__ , netns_path , strerror (errno ));
614+ goto err ;
615+ }
616+
617+ req .n .nlmsg_len = NLMSG_LENGTH (sizeof (req .i ));
618+ req .n .nlmsg_type = RTM_SETLINK ;
619+ req .n .nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK ;
620+
621+ req .i .ifi_family = AF_UNSPEC ;
622+ req .i .ifi_index = ifindex ;
623+
624+ SITNL_ADDATTR (& req .n , sizeof (req ),
625+ IFLA_NET_NS_FD ,
626+ & netns_fd ,
627+ sizeof (netns_fd ));
628+
629+ msg (D_ROUTE , "%s: move %s to netns %s" ,
630+ __func__ , iface , netns_path );
631+
632+ ret = sitnl_send (& req .n , 0 , 0 , NULL , NULL );
633+
634+ err :
635+ if (netns_fd >= 0 )
636+ {
637+ close (netns_fd );
638+ }
639+ return ret ;
640+ }
641+
532642static int
533643sitnl_route_best_gw (sa_family_t af_family , const inet_address_t * dst , void * best_gw ,
534644 char * best_iface )
661771net_iface_up (openvpn_net_ctx_t * ctx , const char * iface , bool up )
662772{
663773 struct sitnl_link_req req ;
664- int ifindex ;
774+ int ifindex , netnsid = 0 ;
775+ int ret = -1 ;
665776
666777 CLEAR (req );
667778
@@ -671,7 +782,7 @@ net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up)
671782 return - EINVAL ;
672783 }
673784
674- ifindex = if_nametoindex (iface );
785+ ifindex = openvpn_if_nametoindex (iface , netnsid );
675786 if (ifindex == 0 )
676787 {
677788 msg (M_WARN , "%s: rtnl: cannot get ifindex for %s: %s" , __func__ , iface , strerror (errno ));
@@ -685,9 +796,11 @@ net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up)
685796 req .i .ifi_family = AF_PACKET ;
686797 req .i .ifi_index = ifindex ;
687798 req .i .ifi_change |= IFF_UP ;
799+
688800 if (up )
689801 {
690802 req .i .ifi_flags |= IFF_UP ;
803+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_TARGET_NETNSID , & netnsid , sizeof (int ));
691804 }
692805 else
693806 {
@@ -696,31 +809,36 @@ net_iface_up(openvpn_net_ctx_t *ctx, const char *iface, bool up)
696809
697810 msg (M_INFO , "%s: set %s %s" , __func__ , iface , up ? "up" : "down" );
698811
699- return sitnl_send (& req .n , 0 , 0 , NULL , NULL );
812+ ret = sitnl_send (& req .n , 0 , 0 , NULL , NULL );
813+
814+ err :
815+ return ret ;
700816}
701817
702818int
703819net_iface_mtu_set (openvpn_net_ctx_t * ctx , const char * iface , uint32_t mtu )
704820{
705821 struct sitnl_link_req req ;
706822 int ifindex , ret = -1 ;
823+ int netnsid = 0 ;
707824
708825 CLEAR (req );
709826
710- ifindex = if_nametoindex (iface );
827+ ifindex = openvpn_if_nametoindex (iface , netnsid );
711828 if (ifindex == 0 )
712829 {
713830 msg (M_WARN | M_ERRNO , "%s: rtnl: cannot get ifindex for %s" , __func__ , iface );
714831 return -1 ;
715832 }
716833
717834 req .n .nlmsg_len = NLMSG_LENGTH (sizeof (req .i ));
718- req .n .nlmsg_flags = NLM_F_REQUEST ;
835+ req .n .nlmsg_flags = 0 ; // NLM_F_REQUEST;
719836 req .n .nlmsg_type = RTM_NEWLINK ;
720837
721838 req .i .ifi_family = AF_PACKET ;
722839 req .i .ifi_index = ifindex ;
723840
841+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_TARGET_NETNSID , & netnsid , sizeof (int ));
724842 SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_MTU , & mtu , 4 );
725843
726844 msg (M_INFO , "%s: mtu %u for %s" , __func__ , mtu , iface );
@@ -734,25 +852,26 @@ int
734852net_addr_ll_set (openvpn_net_ctx_t * ctx , const openvpn_net_iface_t * iface , uint8_t * addr )
735853{
736854 struct sitnl_link_req req ;
737- int ifindex , ret = -1 ;
855+ int ifindex , ret = -1 , netnsid = 0 ;
738856
739857 CLEAR (req );
740858
741- ifindex = if_nametoindex (iface );
859+ ifindex = openvpn_if_nametoindex (iface , netnsid );
742860 if (ifindex == 0 )
743861 {
744862 msg (M_WARN | M_ERRNO , "%s: rtnl: cannot get ifindex for %s" , __func__ , iface );
745863 return -1 ;
746864 }
747865
748866 req .n .nlmsg_len = NLMSG_LENGTH (sizeof (req .i ));
749- req .n .nlmsg_flags = NLM_F_REQUEST ;
867+ req .n .nlmsg_flags = NLM_F_REQUEST ;;
750868 req .n .nlmsg_type = RTM_NEWLINK ;
751869
752870 req .i .ifi_family = AF_PACKET ;
753871 req .i .ifi_index = ifindex ;
754872
755873 SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_ADDRESS , addr , OPENVPN_ETH_ALEN );
874+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_TARGET_NETNSID , & netnsid , sizeof (int ));
756875
757876 msg (M_INFO , "%s: lladdr " MAC_FMT " for %s" , __func__ , MAC_PRINT_ARG (addr ), iface );
758877
@@ -768,12 +887,14 @@ sitnl_addr_set(uint16_t cmd, uint16_t flags, int ifindex, sa_family_t af_family,
768887 struct sitnl_addr_req req ;
769888 uint32_t size ;
770889 int ret = - EINVAL ;
890+ int netnsid = 0 ;
771891
772892 CLEAR (req );
773893
774894 req .n .nlmsg_len = NLMSG_LENGTH (sizeof (req .i ));
775895 req .n .nlmsg_type = cmd ;
776896 req .n .nlmsg_flags = NLM_F_REQUEST | flags ;
897+ // NLM_F_REQUEST | flags;
777898
778899 req .i .ifa_index = ifindex ;
779900 ASSERT (af_family <= UINT8_MAX );
@@ -802,6 +923,8 @@ sitnl_addr_set(uint16_t cmd, uint16_t flags, int ifindex, sa_family_t af_family,
802923 ASSERT (prefixlen <= UINT8_MAX );
803924 req .i .ifa_prefixlen = (uint8_t )prefixlen ;
804925
926+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_TARGET_NETNSID , & netnsid , sizeof (int ));
927+
805928 if (remote )
806929 {
807930 SITNL_ADDATTR (& req .n , sizeof (req ), IFA_ADDRESS , remote , size );
@@ -984,7 +1107,7 @@ sitnl_addr_add(sa_family_t af_family, const char *iface, const inet_address_t *a
9841107 return - EINVAL ;
9851108 }
9861109
987- ifindex = if_nametoindex (iface );
1110+ ifindex = openvpn_if_nametoindex (iface , 0 );
9881111 if (ifindex == 0 )
9891112 {
9901113 msg (M_WARN | M_ERRNO , "%s: rtnl: cannot get ifindex for %s" , __func__ , iface );
@@ -1016,7 +1139,7 @@ sitnl_addr_del(sa_family_t af_family, const char *iface, inet_address_t *addr, i
10161139 return - EINVAL ;
10171140 }
10181141
1019- ifindex = if_nametoindex (iface );
1142+ ifindex = openvpn_if_nametoindex (iface , 0 );
10201143 if (ifindex == 0 )
10211144 {
10221145 msg (M_WARN | M_ERRNO , "%s: rtnl: cannot get ifindex for %s" , __func__ , iface );
@@ -1330,6 +1453,15 @@ net_iface_new(openvpn_net_ctx_t *ctx, const char *iface, const char *type, void
13301453
13311454 SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_IFNAME , iface , strlen (iface ) + 1 );
13321455
1456+ netns_fd = open ("/var/run/netns/ns-test" , O_RDONLY );
1457+ if (netns_fd < 0 )
1458+ {
1459+ msg (M_ERR , "%s: open(/var/run/netns/ns-test) failed: %s" ,
1460+ __func__ , strerror (errno ));
1461+ goto err ;
1462+ }
1463+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_NET_NS_FD , & netns_fd , sizeof (netns_fd ));
1464+
13331465 struct rtattr * linkinfo = SITNL_NEST (& req .n , sizeof (req ), IFLA_LINKINFO );
13341466 SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_INFO_KIND , type , strlen (type ) + 1 );
13351467#if defined(ENABLE_DCO )
@@ -1460,7 +1592,8 @@ int
14601592net_iface_del (openvpn_net_ctx_t * ctx , const char * iface )
14611593{
14621594 struct sitnl_link_req req = {};
1463- int ifindex = if_nametoindex (iface );
1595+ int netnsid = 0 , ret = -1 ;
1596+ int ifindex = openvpn_if_nametoindex (iface , netnsid );
14641597
14651598 if (!ifindex )
14661599 {
@@ -1471,12 +1604,17 @@ net_iface_del(openvpn_net_ctx_t *ctx, const char *iface)
14711604 req .n .nlmsg_flags = NLM_F_REQUEST ;
14721605 req .n .nlmsg_type = RTM_DELLINK ;
14731606
1607+ SITNL_ADDATTR (& req .n , sizeof (req ), IFLA_NET_NS_FD , & netns_fd , sizeof (netns_fd ));
1608+
14741609 req .i .ifi_family = AF_PACKET ;
14751610 req .i .ifi_index = ifindex ;
14761611
14771612 msg (D_ROUTE , "%s: delete %s" , __func__ , iface );
14781613
1479- return sitnl_send (& req .n , 0 , 0 , NULL , NULL );
1614+ ret = sitnl_send (& req .n , 0 , 0 , NULL , NULL );
1615+
1616+ err :
1617+ return ret ;
14801618}
14811619
14821620#endif /* !ENABLE_SITNL */
0 commit comments