@@ -372,45 +372,52 @@ static int parse_ra_flags(uint8_t *flags, struct blob_attr *attr)
372
372
373
373
/* Returns 0 on success, -1 on invalid value, -2 on memory error
374
374
(`routes` is unmodified in that case) */
375
- static int parse_ra_staticroute (struct blob_attr * attr , struct odhcpd_ip6prefix * * routes ,
376
- size_t * routes_cnt )
375
+ static int parse_append_ra_staticroute (struct blob_attr * attr ,
376
+ struct odhcpd_ip6prefix * * routes , size_t * routes_cnt )
377
377
{
378
378
if (blobmsg_type (attr ) != BLOBMSG_TYPE_STRING ||
379
- !blobmsg_check_attr (attr , false))
379
+ !blobmsg_check_attr (attr , false)) {
380
380
return -1 ;
381
+ }
381
382
382
383
const char * str = blobmsg_get_string (attr );
383
- char * astr = malloc (strlen (str ) + 1 );
384
- char * delim ;
385
- int l ;
386
384
struct odhcpd_ip6prefix prefix ;
387
385
388
- if (!astr || !strcpy (astr , str ))
389
- return -2 ;
386
+ /* Parse the address and prefix length */
387
+ if (odhcpd_parse_addr6_prefix (str , & prefix .addr , & prefix .len ) < 0 ) {
388
+ return -1 ;
389
+ }
390
390
391
- if ((delim = strchr (astr , '/' )) == NULL || (* (delim ++ ) = 0 ) ||
392
- sscanf (delim , "%i" , & l ) == 0 || l < 1 || l > 128 ||
393
- inet_pton (AF_INET6 , astr , & prefix .addr ) == 0 ||
394
- IN6_IS_ADDR_UNSPECIFIED (& prefix .addr )) {
391
+ /*
392
+ * Validate prefix length
393
+ * Default route (::/0) is managed elsewhere.
394
+ */
395
+ if (prefix .len == 0 || prefix .len > 128 ) {
395
396
return -1 ;
396
- } else {
397
- prefix .len = l ;
398
-
399
- struct odhcpd_ip6prefix * tmp = realloc (* routes , (* routes_cnt + 1 ) *
400
- sizeof (* * routes ));
401
- if (!tmp ) {
402
- if (astr )
403
- free (astr );
404
- return -2 ;
405
- }
397
+ }
406
398
407
- * routes = tmp ;
408
- (* routes )[* routes_cnt ] = prefix ;
409
- ++ (* routes_cnt );
399
+ /*
400
+ * Validate address
401
+ * Zero-address (::) specifies default route and is managed elsewhere,
402
+ * loopback and link-local addresses are not routable.
403
+ */
404
+ if (IN6_IS_ADDR_UNSPECIFIED (& prefix .addr ) ||
405
+ IN6_IS_ADDR_LOOPBACK (& prefix .addr ) ||
406
+ IN6_IS_ADDR_LINKLOCAL (& prefix .addr )) {
407
+ return -1 ;
410
408
}
411
409
412
- if (astr )
413
- free (astr );
410
+ /* Append the prefix to the list */
411
+ struct odhcpd_ip6prefix * tmp = realloc (* routes , (* routes_cnt + 1 ) *
412
+ sizeof (* * routes ));
413
+ if (!tmp ) {
414
+ return -2 ;
415
+ }
416
+
417
+ * routes = tmp ;
418
+ (* routes )[* routes_cnt ] = prefix ;
419
+ ++ (* routes_cnt );
420
+
414
421
return 0 ;
415
422
}
416
423
@@ -461,15 +468,28 @@ static void set_config(struct uci_section *s)
461
468
unsigned rem ;
462
469
463
470
blobmsg_for_each_attr (cur , c , rem ) {
464
- int ec = parse_ra_staticroute (cur , & (config .ra_static_routes ),
471
+ /* Parse and append the route */
472
+ int ec = parse_append_ra_staticroute (
473
+ cur , & (config .ra_static_routes ),
465
474
& (config .ra_static_routes_cnt ));
466
475
467
476
if (ec == -1 ) {
468
- syslog (LOG_ERR , "Invalid %s value" ,
469
- odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name );
477
+ /* Invalid value */
478
+ char default_str [] = "?" ;
479
+ char * str = default_str ;
480
+ if (blobmsg_type (cur ) == BLOBMSG_TYPE_STRING &&
481
+ blobmsg_check_attr (cur , false)) {
482
+ str = blobmsg_get_string (cur );
483
+ }
484
+ syslog (LOG_WARNING , "Invalid %s value (%s), "
485
+ "ignoring this route" ,
486
+ odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name ,
487
+ str );
470
488
} else if (ec == -2 ) {
489
+ /* Memory error */
471
490
syslog (LOG_ERR , "Memory allocation failed for %s" ,
472
- odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name );
491
+ odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name );
492
+ break ;
473
493
}
474
494
}
475
495
}
@@ -1388,21 +1408,34 @@ int config_parse_interface(void *data, size_t len, const char *name, bool overwr
1388
1408
1389
1409
if ((c = tb [IFACE_ATTR_RA_DNS ]))
1390
1410
iface -> ra_dns = blobmsg_get_bool (c );
1391
-
1411
+
1392
1412
if ((c = tb [IFACE_ATTR_RA_STATICROUTE ])) {
1393
1413
struct blob_attr * cur ;
1394
1414
unsigned rem ;
1395
1415
1396
1416
blobmsg_for_each_attr (cur , c , rem ) {
1397
- int ec = parse_ra_staticroute (cur , & (iface -> ra_static_routes ),
1417
+ /* Parse and append the route */
1418
+ int ec = parse_append_ra_staticroute (
1419
+ cur , & (iface -> ra_static_routes ),
1398
1420
& (iface -> ra_static_routes_cnt ));
1399
1421
1400
1422
if (ec == -1 ) {
1401
- syslog (LOG_ERR , "Invalid %s value configured for interface '%s'" ,
1402
- iface_attrs [IFACE_ATTR_RA_STATICROUTE ].name , iface -> name );
1423
+ /* Invalid value */
1424
+ char default_str [] = "?" ;
1425
+ char * str = default_str ;
1426
+ if (blobmsg_type (cur ) == BLOBMSG_TYPE_STRING &&
1427
+ blobmsg_check_attr (cur , false)) {
1428
+ str = blobmsg_get_string (cur );
1429
+ }
1430
+ syslog (LOG_WARNING , "Invalid %s value (%s) for "
1431
+ "interface '%s', ignoring this route" ,
1432
+ odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name ,
1433
+ str , iface -> name );
1403
1434
} else if (ec == -2 ) {
1404
- syslog (LOG_ERR , "Memory allocation failed for %s on interface '%s'" ,
1405
- iface_attrs [IFACE_ATTR_RA_STATICROUTE ].name , iface -> name );
1435
+ /* Memory error */
1436
+ syslog (LOG_ERR , "Memory allocation failed for %s" ,
1437
+ odhcpd_attrs [ODHCPD_ATTR_RA_STATICROUTE ].name );
1438
+ break ;
1406
1439
}
1407
1440
}
1408
1441
}
0 commit comments