@@ -213,6 +213,15 @@ static int netdev_ipip_sit_fill_message_create(NetDev *netdev, Link *link, sd_ne
213213
214214 assert (t );
215215
216+ if (t -> external ) {
217+ r = sd_netlink_message_append_flag (m , IFLA_IPTUN_COLLECT_METADATA );
218+ if (r < 0 )
219+ return r ;
220+
221+ /* If external mode is enabled, then the following settings should not be appended. */
222+ return 0 ;
223+ }
224+
216225 if (link || t -> assign_to_loopback ) {
217226 r = sd_netlink_message_append_u32 (m , IFLA_IPTUN_LINK , link ? link -> ifindex : LOOPBACK_IFINDEX );
218227 if (r < 0 )
@@ -309,6 +318,15 @@ static int netdev_gre_erspan_fill_message_create(NetDev *netdev, Link *link, sd_
309318
310319 assert (t );
311320
321+ if (t -> external ) {
322+ r = sd_netlink_message_append_flag (m , IFLA_GRE_COLLECT_METADATA );
323+ if (r < 0 )
324+ return r ;
325+
326+ /* If external mode is enabled, then the following settings should not be appended. */
327+ return 0 ;
328+ }
329+
312330 if (link || t -> assign_to_loopback ) {
313331 r = sd_netlink_message_append_u32 (m , IFLA_GRE_LINK , link ? link -> ifindex : LOOPBACK_IFINDEX );
314332 if (r < 0 )
@@ -421,6 +439,15 @@ static int netdev_ip6gre_fill_message_create(NetDev *netdev, Link *link, sd_netl
421439
422440 assert (t );
423441
442+ if (t -> external ) {
443+ r = sd_netlink_message_append_flag (m , IFLA_GRE_COLLECT_METADATA );
444+ if (r < 0 )
445+ return r ;
446+
447+ /* If external mode is enabled, then the following settings should not be appended. */
448+ return 0 ;
449+ }
450+
424451 if (link || t -> assign_to_loopback ) {
425452 r = sd_netlink_message_append_u32 (m , IFLA_GRE_LINK , link ? link -> ifindex : LOOPBACK_IFINDEX );
426453 if (r < 0 )
@@ -553,6 +580,32 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl
553580
554581 assert (t );
555582
583+ switch (t -> ip6tnl_mode ) {
584+ case NETDEV_IP6_TNL_MODE_IP6IP6 :
585+ proto = IPPROTO_IPV6 ;
586+ break ;
587+ case NETDEV_IP6_TNL_MODE_IPIP6 :
588+ proto = IPPROTO_IPIP ;
589+ break ;
590+ case NETDEV_IP6_TNL_MODE_ANYIP6 :
591+ default :
592+ proto = 0 ;
593+ break ;
594+ }
595+
596+ r = sd_netlink_message_append_u8 (m , IFLA_IPTUN_PROTO , proto );
597+ if (r < 0 )
598+ return r ;
599+
600+ if (t -> external ) {
601+ r = sd_netlink_message_append_flag (m , IFLA_IPTUN_COLLECT_METADATA );
602+ if (r < 0 )
603+ return r ;
604+
605+ /* If external mode is enabled, then the following settings should not be appended. */
606+ return 0 ;
607+ }
608+
556609 if (link || t -> assign_to_loopback ) {
557610 r = sd_netlink_message_append_u32 (m , IFLA_IPTUN_LINK , link ? link -> ifindex : LOOPBACK_IFINDEX );
558611 if (r < 0 )
@@ -597,23 +650,6 @@ static int netdev_ip6tnl_fill_message_create(NetDev *netdev, Link *link, sd_netl
597650 return r ;
598651 }
599652
600- switch (t -> ip6tnl_mode ) {
601- case NETDEV_IP6_TNL_MODE_IP6IP6 :
602- proto = IPPROTO_IPV6 ;
603- break ;
604- case NETDEV_IP6_TNL_MODE_IPIP6 :
605- proto = IPPROTO_IPIP ;
606- break ;
607- case NETDEV_IP6_TNL_MODE_ANYIP6 :
608- default :
609- proto = 0 ;
610- break ;
611- }
612-
613- r = sd_netlink_message_append_u8 (m , IFLA_IPTUN_PROTO , proto );
614- if (r < 0 )
615- return r ;
616-
617653 return 0 ;
618654}
619655
@@ -640,6 +676,23 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
640676
641677 assert (t );
642678
679+ if (netdev -> kind == NETDEV_KIND_IP6TNL &&
680+ t -> ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID )
681+ return log_netdev_error_errno (netdev , SYNTHETIC_ERRNO (EINVAL ),
682+ "ip6tnl without mode configured in %s. Ignoring" , filename );
683+
684+ if (t -> external ) {
685+ if (IN_SET (netdev -> kind , NETDEV_KIND_VTI , NETDEV_KIND_VTI6 ))
686+ log_netdev_debug (netdev , "vti/vti6 tunnel do not support external mode, ignoring." );
687+ else {
688+ /* tunnel with external mode does not require underlying interface. */
689+ t -> independent = true;
690+
691+ /* tunnel with external mode does not require any settings checked below. */
692+ return 0 ;
693+ }
694+ }
695+
643696 if (IN_SET (netdev -> kind , NETDEV_KIND_VTI , NETDEV_KIND_IPIP , NETDEV_KIND_SIT , NETDEV_KIND_GRE ) &&
644697 !IN_SET (t -> family , AF_UNSPEC , AF_INET ))
645698 return log_netdev_error_errno (netdev , SYNTHETIC_ERRNO (EINVAL ),
@@ -660,11 +713,6 @@ static int netdev_tunnel_verify(NetDev *netdev, const char *filename) {
660713 return log_netdev_error_errno (netdev , SYNTHETIC_ERRNO (EINVAL ),
661714 "ip6gretap tunnel without a remote IPv6 address configured in %s. Ignoring" , filename );
662715
663- if (netdev -> kind == NETDEV_KIND_IP6TNL &&
664- t -> ip6tnl_mode == _NETDEV_IP6_TNL_MODE_INVALID )
665- return log_netdev_error_errno (netdev , SYNTHETIC_ERRNO (EINVAL ),
666- "ip6tnl without mode configured in %s. Ignoring" , filename );
667-
668716 if (t -> fou_tunnel && t -> fou_destination_port <= 0 )
669717 return log_netdev_error_errno (netdev , SYNTHETIC_ERRNO (EINVAL ),
670718 "FooOverUDP missing port configured in %s. Ignoring" , filename );
0 commit comments