@@ -1484,6 +1484,7 @@ static const struct nla_policy macsec_genl_policy[NUM_MACSEC_ATTR] = {
14841484 [MACSEC_ATTR_IFINDEX ] = { .type = NLA_U32 },
14851485 [MACSEC_ATTR_RXSC_CONFIG ] = { .type = NLA_NESTED },
14861486 [MACSEC_ATTR_SA_CONFIG ] = { .type = NLA_NESTED },
1487+ [MACSEC_ATTR_OFFLOAD ] = { .type = NLA_NESTED },
14871488};
14881489
14891490static const struct nla_policy macsec_genl_rxsc_policy [NUM_MACSEC_RXSC_ATTR ] = {
@@ -1501,6 +1502,10 @@ static const struct nla_policy macsec_genl_sa_policy[NUM_MACSEC_SA_ATTR] = {
15011502 .len = MACSEC_MAX_KEY_LEN , },
15021503};
15031504
1505+ static const struct nla_policy macsec_genl_offload_policy [NUM_MACSEC_OFFLOAD_ATTR ] = {
1506+ [MACSEC_OFFLOAD_ATTR_TYPE ] = { .type = NLA_U8 },
1507+ };
1508+
15041509/* Offloads an operation to a device driver */
15051510static int macsec_offload (int (* const func )(struct macsec_context * ),
15061511 struct macsec_context * ctx )
@@ -2329,6 +2334,126 @@ static int macsec_upd_rxsc(struct sk_buff *skb, struct genl_info *info)
23292334 return ret ;
23302335}
23312336
2337+ static bool macsec_is_configured (struct macsec_dev * macsec )
2338+ {
2339+ struct macsec_secy * secy = & macsec -> secy ;
2340+ struct macsec_tx_sc * tx_sc = & secy -> tx_sc ;
2341+ int i ;
2342+
2343+ if (secy -> n_rx_sc > 0 )
2344+ return true;
2345+
2346+ for (i = 0 ; i < MACSEC_NUM_AN ; i ++ )
2347+ if (tx_sc -> sa [i ])
2348+ return true;
2349+
2350+ return false;
2351+ }
2352+
2353+ static int macsec_upd_offload (struct sk_buff * skb , struct genl_info * info )
2354+ {
2355+ struct nlattr * tb_offload [MACSEC_OFFLOAD_ATTR_MAX + 1 ];
2356+ enum macsec_offload offload , prev_offload ;
2357+ int (* func )(struct macsec_context * ctx );
2358+ struct nlattr * * attrs = info -> attrs ;
2359+ struct net_device * dev , * loop_dev ;
2360+ const struct macsec_ops * ops ;
2361+ struct macsec_context ctx ;
2362+ struct macsec_dev * macsec ;
2363+ struct net * loop_net ;
2364+ int ret ;
2365+
2366+ if (!attrs [MACSEC_ATTR_IFINDEX ])
2367+ return - EINVAL ;
2368+
2369+ if (!attrs [MACSEC_ATTR_OFFLOAD ])
2370+ return - EINVAL ;
2371+
2372+ if (nla_parse_nested_deprecated (tb_offload , MACSEC_OFFLOAD_ATTR_MAX ,
2373+ attrs [MACSEC_ATTR_OFFLOAD ],
2374+ macsec_genl_offload_policy , NULL ))
2375+ return - EINVAL ;
2376+
2377+ dev = get_dev_from_nl (genl_info_net (info ), attrs );
2378+ if (IS_ERR (dev ))
2379+ return PTR_ERR (dev );
2380+ macsec = macsec_priv (dev );
2381+
2382+ offload = nla_get_u8 (tb_offload [MACSEC_OFFLOAD_ATTR_TYPE ]);
2383+ if (macsec -> offload == offload )
2384+ return 0 ;
2385+
2386+ /* Check if the offloading mode is supported by the underlying layers */
2387+ if (offload != MACSEC_OFFLOAD_OFF &&
2388+ !macsec_check_offload (offload , macsec ))
2389+ return - EOPNOTSUPP ;
2390+
2391+ if (offload == MACSEC_OFFLOAD_OFF )
2392+ goto skip_limitation ;
2393+
2394+ /* Check the physical interface isn't offloading another interface
2395+ * first.
2396+ */
2397+ for_each_net (loop_net ) {
2398+ for_each_netdev (loop_net , loop_dev ) {
2399+ struct macsec_dev * priv ;
2400+
2401+ if (!netif_is_macsec (loop_dev ))
2402+ continue ;
2403+
2404+ priv = macsec_priv (loop_dev );
2405+
2406+ if (priv -> real_dev == macsec -> real_dev &&
2407+ priv -> offload != MACSEC_OFFLOAD_OFF )
2408+ return - EBUSY ;
2409+ }
2410+ }
2411+
2412+ skip_limitation :
2413+ /* Check if the net device is busy. */
2414+ if (netif_running (dev ))
2415+ return - EBUSY ;
2416+
2417+ rtnl_lock ();
2418+
2419+ prev_offload = macsec -> offload ;
2420+ macsec -> offload = offload ;
2421+
2422+ /* Check if the device already has rules configured: we do not support
2423+ * rules migration.
2424+ */
2425+ if (macsec_is_configured (macsec )) {
2426+ ret = - EBUSY ;
2427+ goto rollback ;
2428+ }
2429+
2430+ ops = __macsec_get_ops (offload == MACSEC_OFFLOAD_OFF ? prev_offload : offload ,
2431+ macsec , & ctx );
2432+ if (!ops ) {
2433+ ret = - EOPNOTSUPP ;
2434+ goto rollback ;
2435+ }
2436+
2437+ if (prev_offload == MACSEC_OFFLOAD_OFF )
2438+ func = ops -> mdo_add_secy ;
2439+ else
2440+ func = ops -> mdo_del_secy ;
2441+
2442+ ctx .secy = & macsec -> secy ;
2443+ ret = macsec_offload (func , & ctx );
2444+ if (ret )
2445+ goto rollback ;
2446+
2447+ rtnl_unlock ();
2448+ return 0 ;
2449+
2450+ rollback :
2451+ macsec -> offload = prev_offload ;
2452+
2453+ rtnl_unlock ();
2454+ return ret ;
2455+ }
2456+
23322457static int copy_tx_sa_stats (struct sk_buff * skb ,
23332458 struct macsec_tx_sa_stats __percpu * pstats )
23342459{
@@ -2590,12 +2715,13 @@ static noinline_for_stack int
25902715dump_secy (struct macsec_secy * secy , struct net_device * dev ,
25912716 struct sk_buff * skb , struct netlink_callback * cb )
25922717{
2593- struct macsec_rx_sc * rx_sc ;
2718+ struct macsec_dev * macsec = netdev_priv ( dev ) ;
25942719 struct macsec_tx_sc * tx_sc = & secy -> tx_sc ;
25952720 struct nlattr * txsa_list , * rxsc_list ;
2596- int i , j ;
2597- void * hdr ;
2721+ struct macsec_rx_sc * rx_sc ;
25982722 struct nlattr * attr ;
2723+ void * hdr ;
2724+ int i , j ;
25992725
26002726 hdr = genlmsg_put (skb , NETLINK_CB (cb -> skb ).portid , cb -> nlh -> nlmsg_seq ,
26012727 & macsec_fam , NLM_F_MULTI , MACSEC_CMD_GET_TXSC );
@@ -2607,6 +2733,13 @@ dump_secy(struct macsec_secy *secy, struct net_device *dev,
26072733 if (nla_put_u32 (skb , MACSEC_ATTR_IFINDEX , dev -> ifindex ))
26082734 goto nla_put_failure ;
26092735
2736+ attr = nla_nest_start_noflag (skb , MACSEC_ATTR_OFFLOAD );
2737+ if (!attr )
2738+ goto nla_put_failure ;
2739+ if (nla_put_u8 (skb , MACSEC_OFFLOAD_ATTR_TYPE , macsec -> offload ))
2740+ goto nla_put_failure ;
2741+ nla_nest_end (skb , attr );
2742+
26102743 if (nla_put_secy (secy , skb ))
26112744 goto nla_put_failure ;
26122745
@@ -2872,6 +3005,12 @@ static const struct genl_ops macsec_genl_ops[] = {
28723005 .doit = macsec_upd_rxsa ,
28733006 .flags = GENL_ADMIN_PERM ,
28743007 },
3008+ {
3009+ .cmd = MACSEC_CMD_UPD_OFFLOAD ,
3010+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP ,
3011+ .doit = macsec_upd_offload ,
3012+ .flags = GENL_ADMIN_PERM ,
3013+ },
28753014};
28763015
28773016static struct genl_family macsec_fam __ro_after_init = {
0 commit comments