@@ -1139,6 +1139,115 @@ __ni_process_ifinfomsg(ni_linkinfo_t *link, struct nlmsghdr *h,
11391139 return __ni_process_ifinfomsg_linkinfo (link , ifname , tb , h , ifi , nc );
11401140}
11411141
1142+ static int
1143+ __ni_process_ifinfomsg_af_ipv4_conf (ni_netdev_t * dev , struct nlattr * nla )
1144+ {
1145+ int32_t * array ;
1146+ int bytes ;
1147+
1148+ array = nla_data (nla );
1149+ bytes = nla_len (nla );
1150+ if (bytes <= 0 || !array || (bytes % 4 ))
1151+ return -1 ;
1152+
1153+ return __ni_ipv4_devconf_process_flags (dev , array , bytes / 4 );
1154+ }
1155+
1156+ static int
1157+ __ni_process_ifinfomsg_af_ipv4 (ni_netdev_t * dev , struct nlattr * nla , ni_bool_t * ipv4_conf )
1158+ {
1159+ struct nlattr * tb [IFLA_INET_MAX + 1 ];
1160+
1161+ if (!nla )
1162+ return -1 ;
1163+
1164+ memset (tb , 0 , sizeof (tb ));
1165+ if (nla_parse_nested (tb , IFLA_INET_MAX , nla , NULL ) < 0 )
1166+ return -1 ;
1167+
1168+ if (tb [IFLA_INET_CONF ]) {
1169+ if (!__ni_process_ifinfomsg_af_ipv4_conf (dev , tb [IFLA_INET_CONF ]) && ipv4_conf )
1170+ * ipv4_conf = TRUE;
1171+ }
1172+
1173+ return 0 ;
1174+ }
1175+
1176+ static int
1177+ __ni_process_ifinfomsg_af_ipv6_conf (ni_netdev_t * dev , struct nlattr * nla )
1178+ {
1179+ int32_t * array ;
1180+ int bytes ;
1181+
1182+ array = nla_data (nla );
1183+ bytes = nla_len (nla );
1184+ if (bytes <= 0 || !array || (bytes % 4 ))
1185+ return -1 ;
1186+
1187+ return __ni_ipv6_devconf_process_flags (dev , array , bytes / 4 );
1188+ }
1189+
1190+ static int
1191+ __ni_process_ifinfomsg_af_ipv6 (ni_netdev_t * dev , struct nlattr * nla , ni_bool_t * ipv6_conf )
1192+ {
1193+ struct nlattr * tb [IFLA_INET6_MAX + 1 ];
1194+
1195+ if (!nla )
1196+ return -1 ;
1197+
1198+ memset (tb , 0 , sizeof (tb ));
1199+ if (nla_parse_nested (tb , IFLA_INET6_MAX , nla , NULL ) < 0 )
1200+ return -1 ;
1201+
1202+ if (tb [IFLA_INET6_CONF ]) {
1203+ if (!__ni_process_ifinfomsg_af_ipv6_conf (dev , tb [IFLA_INET6_CONF ]) && ipv6_conf )
1204+ * ipv6_conf = TRUE;
1205+ }
1206+
1207+ return 0 ;
1208+ }
1209+
1210+ static int
1211+ __ni_process_ifinfomsg_af_spec (ni_netdev_t * dev , struct nlattr * ifla_af_spec )
1212+ {
1213+ /*
1214+ * not every newlink provides device sysctl's;
1215+ * we get them on a refresh and on any change
1216+ * and this is IMO completely sufficient.
1217+ */
1218+ static ni_bool_t ipv4_conf = FALSE;
1219+ static ni_bool_t ipv6_conf = FALSE;
1220+
1221+ if (ifla_af_spec ) {
1222+ struct nlattr * af ;
1223+ int rem ;
1224+
1225+ nla_for_each_nested (af , ifla_af_spec , rem ) {
1226+ switch (nla_type (af )) {
1227+ case AF_INET :
1228+ __ni_process_ifinfomsg_af_ipv4 (dev , af , & ipv4_conf );
1229+ break ;
1230+ case AF_INET6 :
1231+ __ni_process_ifinfomsg_af_ipv6 (dev , af , & ipv6_conf );
1232+ break ;
1233+ default :
1234+ break ;
1235+ }
1236+ }
1237+ }
1238+
1239+ /* don't read sysfs when device (name) is not ready */
1240+ if (ni_netdev_device_is_ready (dev )) {
1241+ if (!ipv4_conf ) {
1242+ ni_system_ipv4_devinfo_get (dev , NULL );
1243+ }
1244+ if (!ipv6_conf ) {
1245+ ni_system_ipv6_devinfo_get (dev , NULL );
1246+ }
1247+ }
1248+
1249+ return 0 ;
1250+ }
11421251
11431252/*
11441253 * Refresh complete interface link info given a RTM_NEWLINK message
@@ -1182,9 +1291,7 @@ __ni_netdev_process_newlink(ni_netdev_t *dev, struct nlmsghdr *h,
11821291 ni_oper_state_type_to_name (dev -> link .oper_state ));
11831292#endif
11841293
1185- ni_system_ipv4_devinfo_get (dev , NULL );
1186- ni_system_ipv6_devinfo_get (dev , NULL );
1187-
1294+ __ni_process_ifinfomsg_af_spec (dev , tb [IFLA_AF_SPEC ]);
11881295 __ni_process_ifinfomsg_ipv6info (dev , tb [IFLA_PROTINFO ]);
11891296
11901297 switch (dev -> link .type ) {
0 commit comments