@@ -5051,6 +5051,44 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
5051
5051
[RTA_FLOWLABEL ] = { .type = NLA_BE32 },
5052
5052
};
5053
5053
5054
+ static int rtm_to_fib6_multipath_config (struct fib6_config * cfg ,
5055
+ struct netlink_ext_ack * extack )
5056
+ {
5057
+ struct rtnexthop * rtnh ;
5058
+ int remaining ;
5059
+
5060
+ remaining = cfg -> fc_mp_len ;
5061
+ rtnh = (struct rtnexthop * )cfg -> fc_mp ;
5062
+
5063
+ if (!rtnh_ok (rtnh , remaining )) {
5064
+ NL_SET_ERR_MSG (extack , "Invalid nexthop configuration - no valid nexthops" );
5065
+ return - EINVAL ;
5066
+ }
5067
+
5068
+ do {
5069
+ int attrlen = rtnh_attrlen (rtnh );
5070
+
5071
+ if (attrlen > 0 ) {
5072
+ struct nlattr * nla , * attrs ;
5073
+
5074
+ attrs = rtnh_attrs (rtnh );
5075
+ nla = nla_find (attrs , attrlen , RTA_GATEWAY );
5076
+ if (nla ) {
5077
+ if (nla_len (nla ) < sizeof (cfg -> fc_gateway )) {
5078
+ NL_SET_ERR_MSG (extack ,
5079
+ "Invalid IPv6 address in RTA_GATEWAY" );
5080
+ return - EINVAL ;
5081
+ }
5082
+ }
5083
+ }
5084
+
5085
+ rtnh = rtnh_next (rtnh , & remaining );
5086
+ } while (rtnh_ok (rtnh , remaining ));
5087
+
5088
+ return lwtunnel_valid_encap_type_attr (cfg -> fc_mp , cfg -> fc_mp_len ,
5089
+ extack , true);
5090
+ }
5091
+
5054
5092
static int rtm_to_fib6_config (struct sk_buff * skb , struct nlmsghdr * nlh ,
5055
5093
struct fib6_config * cfg ,
5056
5094
struct netlink_ext_ack * extack )
@@ -5165,9 +5203,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
5165
5203
cfg -> fc_mp = nla_data (tb [RTA_MULTIPATH ]);
5166
5204
cfg -> fc_mp_len = nla_len (tb [RTA_MULTIPATH ]);
5167
5205
5168
- err = lwtunnel_valid_encap_type_attr (cfg -> fc_mp ,
5169
- cfg -> fc_mp_len ,
5170
- extack , true);
5206
+ err = rtm_to_fib6_multipath_config (cfg , extack );
5171
5207
if (err < 0 )
5172
5208
goto errout ;
5173
5209
}
@@ -5287,19 +5323,6 @@ static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
5287
5323
return should_notify ;
5288
5324
}
5289
5325
5290
- static int fib6_gw_from_attr (struct in6_addr * gw , struct nlattr * nla ,
5291
- struct netlink_ext_ack * extack )
5292
- {
5293
- if (nla_len (nla ) < sizeof (* gw )) {
5294
- NL_SET_ERR_MSG (extack , "Invalid IPv6 address in RTA_GATEWAY" );
5295
- return - EINVAL ;
5296
- }
5297
-
5298
- * gw = nla_get_in6_addr (nla );
5299
-
5300
- return 0 ;
5301
- }
5302
-
5303
5326
static int ip6_route_multipath_add (struct fib6_config * cfg ,
5304
5327
struct netlink_ext_ack * extack )
5305
5328
{
@@ -5340,18 +5363,11 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
5340
5363
5341
5364
nla = nla_find (attrs , attrlen , RTA_GATEWAY );
5342
5365
if (nla ) {
5343
- err = fib6_gw_from_attr (& r_cfg .fc_gateway , nla ,
5344
- extack );
5345
- if (err )
5346
- goto cleanup ;
5347
-
5366
+ r_cfg .fc_gateway = nla_get_in6_addr (nla );
5348
5367
r_cfg .fc_flags |= RTF_GATEWAY ;
5349
5368
}
5350
- r_cfg .fc_encap = nla_find (attrs , attrlen , RTA_ENCAP );
5351
5369
5352
- /* RTA_ENCAP_TYPE length checked in
5353
- * lwtunnel_valid_encap_type_attr
5354
- */
5370
+ r_cfg .fc_encap = nla_find (attrs , attrlen , RTA_ENCAP );
5355
5371
nla = nla_find (attrs , attrlen , RTA_ENCAP_TYPE );
5356
5372
if (nla )
5357
5373
r_cfg .fc_encap_type = nla_get_u16 (nla );
@@ -5384,12 +5400,6 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
5384
5400
rtnh = rtnh_next (rtnh , & remaining );
5385
5401
}
5386
5402
5387
- if (list_empty (& rt6_nh_list )) {
5388
- NL_SET_ERR_MSG (extack ,
5389
- "Invalid nexthop configuration - no valid nexthops" );
5390
- return - EINVAL ;
5391
- }
5392
-
5393
5403
/* for add and replace send one notification with all nexthops.
5394
5404
* Skip the notification in fib6_add_rt2node and send one with
5395
5405
* the full route when done
@@ -5511,21 +5521,15 @@ static int ip6_route_multipath_del(struct fib6_config *cfg,
5511
5521
5512
5522
nla = nla_find (attrs , attrlen , RTA_GATEWAY );
5513
5523
if (nla ) {
5514
- err = fib6_gw_from_attr (& r_cfg .fc_gateway , nla ,
5515
- extack );
5516
- if (err ) {
5517
- last_err = err ;
5518
- goto next_rtnh ;
5519
- }
5520
-
5524
+ r_cfg .fc_gateway = nla_get_in6_addr (nla );
5521
5525
r_cfg .fc_flags |= RTF_GATEWAY ;
5522
5526
}
5523
5527
}
5528
+
5524
5529
err = ip6_route_del (& r_cfg , extack );
5525
5530
if (err )
5526
5531
last_err = err ;
5527
5532
5528
- next_rtnh :
5529
5533
rtnh = rtnh_next (rtnh , & remaining );
5530
5534
}
5531
5535
0 commit comments