@@ -2178,6 +2178,7 @@ handle_generic_vlans(NetplanParser* npp, yaml_node_t* node, GArray** entryptr, G
21782178 re_inited = TRUE;
21792179 }
21802180
2181+ unsigned pvids = 0 ;
21812182 for (yaml_node_item_t * i = node -> data .sequence .items .start ; i < node -> data .sequence .items .top ; i ++ ) {
21822183 g_autofree char * vlan = NULL ;
21832184 yaml_node_t * entry = yaml_document_get_node (& npp -> doc , * i );
@@ -2187,6 +2188,9 @@ handle_generic_vlans(NetplanParser* npp, yaml_node_t* node, GArray** entryptr, G
21872188
21882189 size_t maxGroups = 7 + 1 ;
21892190 regmatch_t groups [maxGroups ];
2191+
2192+ guint minVid = npp -> global_backend == NETPLAN_BACKEND_NETWORKD ? 0 :1 ;
2193+
21902194 /* does it match the vlans= definition? */
21912195 if (regexec (& re , vlan , maxGroups , groups , 0 ) == 0 ) {
21922196 NetplanBridgeVlan * data = g_new0 (NetplanBridgeVlan , 1 );
@@ -2201,27 +2205,50 @@ handle_generic_vlans(NetplanParser* npp, yaml_node_t* node, GArray** entryptr, G
22012205 switch (g ) {
22022206 case 1 :
22032207 v = (guint ) g_ascii_strtoull (cursorCopy + groups [g ].rm_so , NULL , 10 );
2204- if (v < 1 || v > 4094 )
2205- return yaml_error (npp , node , error , "malformed vlan vid '%u', must be in range [1..4094]" , v );
2208+ if (v < minVid || v > 4094 ) {
2209+ g_free (data );
2210+ return yaml_error (npp , node , error , "malformed vlan vid '%u', must be in range [%d..4094]" , v , minVid );
2211+ }
22062212 data -> vid = v ;
22072213 break ;
22082214 case 3 :
22092215 v = (guint ) g_ascii_strtoull (cursorCopy + groups [g ].rm_so , NULL , 10 );
2210- if (v < 1 || v > 4094 )
2216+ if (v < 1 || v > 4094 ) {
2217+ g_free (data );
22112218 return yaml_error (npp , node , error , "malformed vlan vid '%u', must be in range [1..4094]" , v );
2212- else if (v <= data -> vid )
2213- return yaml_error (npp , node , error , "malformed vlan vid range '%s': %u > %u!" , scalar (entry ), data -> vid , v );
2219+ }
2220+
2221+ else if (v <= data -> vid ) {
2222+ guint vid = data -> vid ;
2223+ g_free (data );
2224+ return yaml_error (npp , node , error , "malformed vlan vid range '%s': %u > %u!" , scalar (entry ), vid , v );
2225+ }
2226+
22142227 data -> vid_to = v ;
22152228 break ;
22162229 case 5 :
22172230 data -> pvid = TRUE;
2231+ if (++ pvids > 1 ) {
2232+ g_free (data );
2233+ return yaml_error (npp , node , error , "malformed vlan pvid '%s': only single pvid can be defined" , scalar (entry ));
2234+ }
22182235 break ;
22192236 case 7 :
22202237 data -> untagged = TRUE;
22212238 break ;
22222239 default : g_assert_not_reached (); // LCOV_EXCL_LINE
22232240 }
22242241 }
2242+
2243+ if (npp -> global_backend == NETPLAN_BACKEND_NETWORKD && !data -> pvid && data -> vid == 0 ) {
2244+ g_free (data );
2245+ return yaml_error (npp , node , error , "malformed vlan '%s': value cannot be defined as 0 for non-pvid" , scalar (entry ));
2246+ }
2247+
2248+ if (data -> vid_to > 0 && data -> pvid ) {
2249+ g_free (data );
2250+ return yaml_error (npp , node , error , "malformed vlan '%s': pvid cannot be defined as a range" , scalar (entry ));
2251+ }
22252252 if (!* entryptr )
22262253 * entryptr = g_array_new (FALSE, FALSE, sizeof (NetplanBridgeVlan * ));
22272254 g_array_append_val (* entryptr , data );
@@ -2269,6 +2296,24 @@ handle_bridge_port_vlans(NetplanParser* npp, yaml_node_t* node, const char*, con
22692296 return TRUE;
22702297}
22712298
2299+ /**
2300+ * Handler for vlan-default-pvid.
2301+ * @data: offset into NetplanNetDefinition where the const char* field to write is
2302+ * located
2303+ */
2304+ STATIC gboolean
2305+ handle_vlan_default_pvid (NetplanParser * npp , yaml_node_t * node , const void * data , GError * * error )
2306+ {
2307+ const char * pvid = scalar (node );
2308+ GError * * err = NULL ;
2309+ guint64 val = 0 ;
2310+ if (strcmp (pvid , "none" ) != 0 && !g_ascii_string_to_unsigned (pvid , 10 , 1 , 4094 , & val , err )) {
2311+ return yaml_error (npp , node , error , "malformed value of vlan-default-pvid '%s': vlan-default-pvid can only be defined as a single port ID" , pvid );
2312+ }
2313+
2314+ return handle_netdef_str (npp , node , data , error );
2315+ }
2316+
22722317static const mapping_entry_handler bridge_params_handlers [] = {
22732318 {"ageing-time" , YAML_SCALAR_NODE , {.generic = handle_netdef_str }, netdef_offset (bridge_params .ageing_time )},
22742319 {"aging-time" , YAML_SCALAR_NODE , {.generic = handle_netdef_str }, netdef_offset (bridge_params .ageing_time )},
@@ -2282,6 +2327,7 @@ static const mapping_entry_handler bridge_params_handlers[] = {
22822327 {"port-vlans" , YAML_MAPPING_NODE , {.map = {.custom = handle_bridge_port_vlans }}, netdef_offset (bridge_params .port_vlans )},
22832328 {"vlans" , YAML_SEQUENCE_NODE , {.generic = handle_bridge_vlans }, netdef_offset (bridge_params .vlans )},
22842329 {"vlan-filtering" , YAML_SCALAR_NODE , {.generic = handle_netdef_bool }, netdef_offset (bridge_params .vlan_filtering )},
2330+ {"vlan-default-pvid" , YAML_SCALAR_NODE , {.generic = handle_vlan_default_pvid }, netdef_offset (bridge_params .vlan_default_pvid )},
22852331 {NULL }
22862332};
22872333
0 commit comments