@@ -4496,6 +4496,53 @@ void rt6_purge_dflt_routers(struct net *net)
4496
4496
rcu_read_unlock ();
4497
4497
}
4498
4498
4499
+ static int fib6_config_validate (struct fib6_config * cfg ,
4500
+ struct netlink_ext_ack * extack )
4501
+ {
4502
+ /* RTF_PCPU is an internal flag; can not be set by userspace */
4503
+ if (cfg -> fc_flags & RTF_PCPU ) {
4504
+ NL_SET_ERR_MSG (extack , "Userspace can not set RTF_PCPU" );
4505
+ goto errout ;
4506
+ }
4507
+
4508
+ /* RTF_CACHE is an internal flag; can not be set by userspace */
4509
+ if (cfg -> fc_flags & RTF_CACHE ) {
4510
+ NL_SET_ERR_MSG (extack , "Userspace can not set RTF_CACHE" );
4511
+ goto errout ;
4512
+ }
4513
+
4514
+ if (cfg -> fc_type > RTN_MAX ) {
4515
+ NL_SET_ERR_MSG (extack , "Invalid route type" );
4516
+ goto errout ;
4517
+ }
4518
+
4519
+ if (cfg -> fc_dst_len > 128 ) {
4520
+ NL_SET_ERR_MSG (extack , "Invalid prefix length" );
4521
+ goto errout ;
4522
+ }
4523
+
4524
+ #ifdef CONFIG_IPV6_SUBTREES
4525
+ if (cfg -> fc_src_len > 128 ) {
4526
+ NL_SET_ERR_MSG (extack , "Invalid source address length" );
4527
+ goto errout ;
4528
+ }
4529
+
4530
+ if (cfg -> fc_nh_id && cfg -> fc_src_len ) {
4531
+ NL_SET_ERR_MSG (extack , "Nexthops can not be used with source routing" );
4532
+ goto errout ;
4533
+ }
4534
+ #else
4535
+ if (cfg -> fc_src_len ) {
4536
+ NL_SET_ERR_MSG (extack ,
4537
+ "Specifying source address requires IPV6_SUBTREES to be enabled" );
4538
+ goto errout ;
4539
+ }
4540
+ #endif
4541
+ return 0 ;
4542
+ errout :
4543
+ return - EINVAL ;
4544
+ }
4545
+
4499
4546
static void rtmsg_to_fib6_config (struct net * net ,
4500
4547
struct in6_rtmsg * rtmsg ,
4501
4548
struct fib6_config * cfg )
@@ -4533,6 +4580,10 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, struct in6_rtmsg *rtmsg)
4533
4580
4534
4581
switch (cmd ) {
4535
4582
case SIOCADDRT :
4583
+ err = fib6_config_validate (& cfg , NULL );
4584
+ if (err )
4585
+ break ;
4586
+
4536
4587
/* Only do the default setting of fc_metric in route adding */
4537
4588
if (cfg .fc_metric == 0 )
4538
4589
cfg .fc_metric = IP6_RT_PRIO_USER ;
@@ -5267,48 +5318,6 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
5267
5318
}
5268
5319
}
5269
5320
5270
- if (newroute ) {
5271
- /* RTF_PCPU is an internal flag; can not be set by userspace */
5272
- if (cfg -> fc_flags & RTF_PCPU ) {
5273
- NL_SET_ERR_MSG (extack , "Userspace can not set RTF_PCPU" );
5274
- goto errout ;
5275
- }
5276
-
5277
- /* RTF_CACHE is an internal flag; can not be set by userspace */
5278
- if (cfg -> fc_flags & RTF_CACHE ) {
5279
- NL_SET_ERR_MSG (extack , "Userspace can not set RTF_CACHE" );
5280
- goto errout ;
5281
- }
5282
-
5283
- if (cfg -> fc_type > RTN_MAX ) {
5284
- NL_SET_ERR_MSG (extack , "Invalid route type" );
5285
- goto errout ;
5286
- }
5287
-
5288
- if (cfg -> fc_dst_len > 128 ) {
5289
- NL_SET_ERR_MSG (extack , "Invalid prefix length" );
5290
- goto errout ;
5291
- }
5292
-
5293
- #ifdef CONFIG_IPV6_SUBTREES
5294
- if (cfg -> fc_src_len > 128 ) {
5295
- NL_SET_ERR_MSG (extack , "Invalid source address length" );
5296
- goto errout ;
5297
- }
5298
-
5299
- if (cfg -> fc_nh_id && cfg -> fc_src_len ) {
5300
- NL_SET_ERR_MSG (extack , "Nexthops can not be used with source routing" );
5301
- goto errout ;
5302
- }
5303
- #else
5304
- if (cfg -> fc_src_len ) {
5305
- NL_SET_ERR_MSG (extack ,
5306
- "Specifying source address requires IPV6_SUBTREES to be enabled" );
5307
- goto errout ;
5308
- }
5309
- #endif
5310
- }
5311
-
5312
5321
err = 0 ;
5313
5322
errout :
5314
5323
return err ;
@@ -5703,6 +5712,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
5703
5712
if (err < 0 )
5704
5713
return err ;
5705
5714
5715
+ err = fib6_config_validate (cfg , extack );
5716
+ if (err )
5717
+ return err ;
5718
+
5706
5719
if (cfg .fc_metric == 0 )
5707
5720
cfg .fc_metric = IP6_RT_PRIO_USER ;
5708
5721
0 commit comments