@@ -4503,6 +4503,53 @@ void rt6_purge_dflt_routers(struct net *net)
4503
4503
rcu_read_unlock ();
4504
4504
}
4505
4505
4506
+ static int fib6_config_validate (struct fib6_config * cfg ,
4507
+ struct netlink_ext_ack * extack )
4508
+ {
4509
+ /* RTF_PCPU is an internal flag; can not be set by userspace */
4510
+ if (cfg -> fc_flags & RTF_PCPU ) {
4511
+ NL_SET_ERR_MSG (extack , "Userspace can not set RTF_PCPU" );
4512
+ goto errout ;
4513
+ }
4514
+
4515
+ /* RTF_CACHE is an internal flag; can not be set by userspace */
4516
+ if (cfg -> fc_flags & RTF_CACHE ) {
4517
+ NL_SET_ERR_MSG (extack , "Userspace can not set RTF_CACHE" );
4518
+ goto errout ;
4519
+ }
4520
+
4521
+ if (cfg -> fc_type > RTN_MAX ) {
4522
+ NL_SET_ERR_MSG (extack , "Invalid route type" );
4523
+ goto errout ;
4524
+ }
4525
+
4526
+ if (cfg -> fc_dst_len > 128 ) {
4527
+ NL_SET_ERR_MSG (extack , "Invalid prefix length" );
4528
+ goto errout ;
4529
+ }
4530
+
4531
+ #ifdef CONFIG_IPV6_SUBTREES
4532
+ if (cfg -> fc_src_len > 128 ) {
4533
+ NL_SET_ERR_MSG (extack , "Invalid source address length" );
4534
+ goto errout ;
4535
+ }
4536
+
4537
+ if (cfg -> fc_nh_id && cfg -> fc_src_len ) {
4538
+ NL_SET_ERR_MSG (extack , "Nexthops can not be used with source routing" );
4539
+ goto errout ;
4540
+ }
4541
+ #else
4542
+ if (cfg -> fc_src_len ) {
4543
+ NL_SET_ERR_MSG (extack ,
4544
+ "Specifying source address requires IPV6_SUBTREES to be enabled" );
4545
+ goto errout ;
4546
+ }
4547
+ #endif
4548
+ return 0 ;
4549
+ errout :
4550
+ return - EINVAL ;
4551
+ }
4552
+
4506
4553
static void rtmsg_to_fib6_config (struct net * net ,
4507
4554
struct in6_rtmsg * rtmsg ,
4508
4555
struct fib6_config * cfg )
@@ -4540,6 +4587,10 @@ int ipv6_route_ioctl(struct net *net, unsigned int cmd, struct in6_rtmsg *rtmsg)
4540
4587
4541
4588
switch (cmd ) {
4542
4589
case SIOCADDRT :
4590
+ err = fib6_config_validate (& cfg , NULL );
4591
+ if (err )
4592
+ break ;
4593
+
4543
4594
/* Only do the default setting of fc_metric in route adding */
4544
4595
if (cfg .fc_metric == 0 )
4545
4596
cfg .fc_metric = IP6_RT_PRIO_USER ;
@@ -5274,48 +5325,6 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
5274
5325
}
5275
5326
}
5276
5327
5277
- if (newroute ) {
5278
- /* RTF_PCPU is an internal flag; can not be set by userspace */
5279
- if (cfg -> fc_flags & RTF_PCPU ) {
5280
- NL_SET_ERR_MSG (extack , "Userspace can not set RTF_PCPU" );
5281
- goto errout ;
5282
- }
5283
-
5284
- /* RTF_CACHE is an internal flag; can not be set by userspace */
5285
- if (cfg -> fc_flags & RTF_CACHE ) {
5286
- NL_SET_ERR_MSG (extack , "Userspace can not set RTF_CACHE" );
5287
- goto errout ;
5288
- }
5289
-
5290
- if (cfg -> fc_type > RTN_MAX ) {
5291
- NL_SET_ERR_MSG (extack , "Invalid route type" );
5292
- goto errout ;
5293
- }
5294
-
5295
- if (cfg -> fc_dst_len > 128 ) {
5296
- NL_SET_ERR_MSG (extack , "Invalid prefix length" );
5297
- goto errout ;
5298
- }
5299
-
5300
- #ifdef CONFIG_IPV6_SUBTREES
5301
- if (cfg -> fc_src_len > 128 ) {
5302
- NL_SET_ERR_MSG (extack , "Invalid source address length" );
5303
- goto errout ;
5304
- }
5305
-
5306
- if (cfg -> fc_nh_id && cfg -> fc_src_len ) {
5307
- NL_SET_ERR_MSG (extack , "Nexthops can not be used with source routing" );
5308
- goto errout ;
5309
- }
5310
- #else
5311
- if (cfg -> fc_src_len ) {
5312
- NL_SET_ERR_MSG (extack ,
5313
- "Specifying source address requires IPV6_SUBTREES to be enabled" );
5314
- goto errout ;
5315
- }
5316
- #endif
5317
- }
5318
-
5319
5328
err = 0 ;
5320
5329
errout :
5321
5330
return err ;
@@ -5710,6 +5719,10 @@ static int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
5710
5719
if (err < 0 )
5711
5720
return err ;
5712
5721
5722
+ err = fib6_config_validate (& cfg , extack );
5723
+ if (err )
5724
+ return err ;
5725
+
5713
5726
if (cfg .fc_metric == 0 )
5714
5727
cfg .fc_metric = IP6_RT_PRIO_USER ;
5715
5728
0 commit comments