@@ -5051,6 +5051,44 @@ static const struct nla_policy rtm_ipv6_policy[RTA_MAX+1] = {
50515051 [RTA_FLOWLABEL ] = { .type = NLA_BE32 },
50525052};
50535053
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+
50545092static int rtm_to_fib6_config (struct sk_buff * skb , struct nlmsghdr * nlh ,
50555093 struct fib6_config * cfg ,
50565094 struct netlink_ext_ack * extack )
@@ -5165,9 +5203,7 @@ static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
51655203 cfg -> fc_mp = nla_data (tb [RTA_MULTIPATH ]);
51665204 cfg -> fc_mp_len = nla_len (tb [RTA_MULTIPATH ]);
51675205
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 );
51715207 if (err < 0 )
51725208 goto errout ;
51735209 }
@@ -5287,19 +5323,6 @@ static bool ip6_route_mpath_should_notify(const struct fib6_info *rt)
52875323 return should_notify ;
52885324}
52895325
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-
53035326static int ip6_route_multipath_add (struct fib6_config * cfg ,
53045327 struct netlink_ext_ack * extack )
53055328{
@@ -5340,18 +5363,11 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
53405363
53415364 nla = nla_find (attrs , attrlen , RTA_GATEWAY );
53425365 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 );
53485367 r_cfg .fc_flags |= RTF_GATEWAY ;
53495368 }
5350- r_cfg .fc_encap = nla_find (attrs , attrlen , RTA_ENCAP );
53515369
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 );
53555371 nla = nla_find (attrs , attrlen , RTA_ENCAP_TYPE );
53565372 if (nla )
53575373 r_cfg .fc_encap_type = nla_get_u16 (nla );
@@ -5384,12 +5400,6 @@ static int ip6_route_multipath_add(struct fib6_config *cfg,
53845400 rtnh = rtnh_next (rtnh , & remaining );
53855401 }
53865402
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-
53935403 /* for add and replace send one notification with all nexthops.
53945404 * Skip the notification in fib6_add_rt2node and send one with
53955405 * the full route when done
@@ -5511,21 +5521,15 @@ static int ip6_route_multipath_del(struct fib6_config *cfg,
55115521
55125522 nla = nla_find (attrs , attrlen , RTA_GATEWAY );
55135523 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 );
55215525 r_cfg .fc_flags |= RTF_GATEWAY ;
55225526 }
55235527 }
5528+
55245529 err = ip6_route_del (& r_cfg , extack );
55255530 if (err )
55265531 last_err = err ;
55275532
5528- next_rtnh :
55295533 rtnh = rtnh_next (rtnh , & remaining );
55305534 }
55315535
0 commit comments