diff options
Diffstat (limited to 'drivers/net/macsec.c')
-rw-r--r-- | drivers/net/macsec.c | 65 |
1 files changed, 42 insertions, 23 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index 84d3e5ca8817..c6385617bfb2 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
@@ -880,12 +880,12 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
880 | macsec_skb_cb(skb)->valid = false; | 880 | macsec_skb_cb(skb)->valid = false; |
881 | skb = skb_share_check(skb, GFP_ATOMIC); | 881 | skb = skb_share_check(skb, GFP_ATOMIC); |
882 | if (!skb) | 882 | if (!skb) |
883 | return NULL; | 883 | return ERR_PTR(-ENOMEM); |
884 | 884 | ||
885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); | 885 | req = aead_request_alloc(rx_sa->key.tfm, GFP_ATOMIC); |
886 | if (!req) { | 886 | if (!req) { |
887 | kfree_skb(skb); | 887 | kfree_skb(skb); |
888 | return NULL; | 888 | return ERR_PTR(-ENOMEM); |
889 | } | 889 | } |
890 | 890 | ||
891 | hdr = (struct macsec_eth_header *)skb->data; | 891 | hdr = (struct macsec_eth_header *)skb->data; |
@@ -905,7 +905,7 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
905 | skb = skb_unshare(skb, GFP_ATOMIC); | 905 | skb = skb_unshare(skb, GFP_ATOMIC); |
906 | if (!skb) { | 906 | if (!skb) { |
907 | aead_request_free(req); | 907 | aead_request_free(req); |
908 | return NULL; | 908 | return ERR_PTR(-ENOMEM); |
909 | } | 909 | } |
910 | } else { | 910 | } else { |
911 | /* integrity only: all headers + data authenticated */ | 911 | /* integrity only: all headers + data authenticated */ |
@@ -921,14 +921,14 @@ static struct sk_buff *macsec_decrypt(struct sk_buff *skb, | |||
921 | dev_hold(dev); | 921 | dev_hold(dev); |
922 | ret = crypto_aead_decrypt(req); | 922 | ret = crypto_aead_decrypt(req); |
923 | if (ret == -EINPROGRESS) { | 923 | if (ret == -EINPROGRESS) { |
924 | return NULL; | 924 | return ERR_PTR(ret); |
925 | } else if (ret != 0) { | 925 | } else if (ret != 0) { |
926 | /* decryption/authentication failed | 926 | /* decryption/authentication failed |
927 | * 10.6 if validateFrames is disabled, deliver anyway | 927 | * 10.6 if validateFrames is disabled, deliver anyway |
928 | */ | 928 | */ |
929 | if (ret != -EBADMSG) { | 929 | if (ret != -EBADMSG) { |
930 | kfree_skb(skb); | 930 | kfree_skb(skb); |
931 | skb = NULL; | 931 | skb = ERR_PTR(ret); |
932 | } | 932 | } |
933 | } else { | 933 | } else { |
934 | macsec_skb_cb(skb)->valid = true; | 934 | macsec_skb_cb(skb)->valid = true; |
@@ -1146,8 +1146,10 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) | |||
1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) | 1146 | secy->validate_frames != MACSEC_VALIDATE_DISABLED) |
1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); | 1147 | skb = macsec_decrypt(skb, dev, rx_sa, sci, secy); |
1148 | 1148 | ||
1149 | if (!skb) { | 1149 | if (IS_ERR(skb)) { |
1150 | macsec_rxsa_put(rx_sa); | 1150 | /* the decrypt callback needs the reference */ |
1151 | if (PTR_ERR(skb) != -EINPROGRESS) | ||
1152 | macsec_rxsa_put(rx_sa); | ||
1151 | rcu_read_unlock(); | 1153 | rcu_read_unlock(); |
1152 | *pskb = NULL; | 1154 | *pskb = NULL; |
1153 | return RX_HANDLER_CONSUMED; | 1155 | return RX_HANDLER_CONSUMED; |
@@ -1161,7 +1163,8 @@ deliver: | |||
1161 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); | 1163 | macsec_extra_len(macsec_skb_cb(skb)->has_sci)); |
1162 | macsec_reset_skb(skb, secy->netdev); | 1164 | macsec_reset_skb(skb, secy->netdev); |
1163 | 1165 | ||
1164 | macsec_rxsa_put(rx_sa); | 1166 | if (rx_sa) |
1167 | macsec_rxsa_put(rx_sa); | ||
1165 | count_rx(dev, skb->len); | 1168 | count_rx(dev, skb->len); |
1166 | 1169 | ||
1167 | rcu_read_unlock(); | 1170 | rcu_read_unlock(); |
@@ -1622,8 +1625,9 @@ static int macsec_add_rxsa(struct sk_buff *skb, struct genl_info *info) | |||
1622 | } | 1625 | } |
1623 | 1626 | ||
1624 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); | 1627 | rx_sa = kmalloc(sizeof(*rx_sa), GFP_KERNEL); |
1625 | if (init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), secy->key_len, | 1628 | if (!rx_sa || init_rx_sa(rx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
1626 | secy->icv_len)) { | 1629 | secy->key_len, secy->icv_len)) { |
1630 | kfree(rx_sa); | ||
1627 | rtnl_unlock(); | 1631 | rtnl_unlock(); |
1628 | return -ENOMEM; | 1632 | return -ENOMEM; |
1629 | } | 1633 | } |
@@ -1768,6 +1772,7 @@ static int macsec_add_txsa(struct sk_buff *skb, struct genl_info *info) | |||
1768 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); | 1772 | tx_sa = kmalloc(sizeof(*tx_sa), GFP_KERNEL); |
1769 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), | 1773 | if (!tx_sa || init_tx_sa(tx_sa, nla_data(tb_sa[MACSEC_SA_ATTR_KEY]), |
1770 | secy->key_len, secy->icv_len)) { | 1774 | secy->key_len, secy->icv_len)) { |
1775 | kfree(tx_sa); | ||
1771 | rtnl_unlock(); | 1776 | rtnl_unlock(); |
1772 | return -ENOMEM; | 1777 | return -ENOMEM; |
1773 | } | 1778 | } |
@@ -2227,7 +2232,8 @@ static int nla_put_secy(struct macsec_secy *secy, struct sk_buff *skb) | |||
2227 | return 1; | 2232 | return 1; |
2228 | 2233 | ||
2229 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || | 2234 | if (nla_put_sci(skb, MACSEC_SECY_ATTR_SCI, secy->sci) || |
2230 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 2235 | nla_put_u64(skb, MACSEC_SECY_ATTR_CIPHER_SUITE, |
2236 | MACSEC_DEFAULT_CIPHER_ID) || | ||
2231 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || | 2237 | nla_put_u8(skb, MACSEC_SECY_ATTR_ICV_LEN, secy->icv_len) || |
2232 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || | 2238 | nla_put_u8(skb, MACSEC_SECY_ATTR_OPER, secy->operational) || |
2233 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || | 2239 | nla_put_u8(skb, MACSEC_SECY_ATTR_PROTECT, secy->protect_frames) || |
@@ -2268,7 +2274,7 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
2268 | if (!hdr) | 2274 | if (!hdr) |
2269 | return -EMSGSIZE; | 2275 | return -EMSGSIZE; |
2270 | 2276 | ||
2271 | rtnl_lock(); | 2277 | genl_dump_check_consistent(cb, hdr, &macsec_fam); |
2272 | 2278 | ||
2273 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) | 2279 | if (nla_put_u32(skb, MACSEC_ATTR_IFINDEX, dev->ifindex)) |
2274 | goto nla_put_failure; | 2280 | goto nla_put_failure; |
@@ -2429,18 +2435,17 @@ static int dump_secy(struct macsec_secy *secy, struct net_device *dev, | |||
2429 | 2435 | ||
2430 | nla_nest_end(skb, rxsc_list); | 2436 | nla_nest_end(skb, rxsc_list); |
2431 | 2437 | ||
2432 | rtnl_unlock(); | ||
2433 | |||
2434 | genlmsg_end(skb, hdr); | 2438 | genlmsg_end(skb, hdr); |
2435 | 2439 | ||
2436 | return 0; | 2440 | return 0; |
2437 | 2441 | ||
2438 | nla_put_failure: | 2442 | nla_put_failure: |
2439 | rtnl_unlock(); | ||
2440 | genlmsg_cancel(skb, hdr); | 2443 | genlmsg_cancel(skb, hdr); |
2441 | return -EMSGSIZE; | 2444 | return -EMSGSIZE; |
2442 | } | 2445 | } |
2443 | 2446 | ||
2447 | static int macsec_generation = 1; /* protected by RTNL */ | ||
2448 | |||
2444 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | 2449 | static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) |
2445 | { | 2450 | { |
2446 | struct net *net = sock_net(skb->sk); | 2451 | struct net *net = sock_net(skb->sk); |
@@ -2450,6 +2455,10 @@ static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) | |||
2450 | dev_idx = cb->args[0]; | 2455 | dev_idx = cb->args[0]; |
2451 | 2456 | ||
2452 | d = 0; | 2457 | d = 0; |
2458 | rtnl_lock(); | ||
2459 | |||
2460 | cb->seq = macsec_generation; | ||
2461 | |||
2453 | for_each_netdev(net, dev) { | 2462 | for_each_netdev(net, dev) { |
2454 | struct macsec_secy *secy; | 2463 | struct macsec_secy *secy; |
2455 | 2464 | ||
@@ -2467,6 +2476,7 @@ next: | |||
2467 | } | 2476 | } |
2468 | 2477 | ||
2469 | done: | 2478 | done: |
2479 | rtnl_unlock(); | ||
2470 | cb->args[0] = d; | 2480 | cb->args[0] = d; |
2471 | return skb->len; | 2481 | return skb->len; |
2472 | } | 2482 | } |
@@ -2920,10 +2930,14 @@ static void macsec_dellink(struct net_device *dev, struct list_head *head) | |||
2920 | struct net_device *real_dev = macsec->real_dev; | 2930 | struct net_device *real_dev = macsec->real_dev; |
2921 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); | 2931 | struct macsec_rxh_data *rxd = macsec_data_rtnl(real_dev); |
2922 | 2932 | ||
2933 | macsec_generation++; | ||
2934 | |||
2923 | unregister_netdevice_queue(dev, head); | 2935 | unregister_netdevice_queue(dev, head); |
2924 | list_del_rcu(&macsec->secys); | 2936 | list_del_rcu(&macsec->secys); |
2925 | if (list_empty(&rxd->secys)) | 2937 | if (list_empty(&rxd->secys)) { |
2926 | netdev_rx_handler_unregister(real_dev); | 2938 | netdev_rx_handler_unregister(real_dev); |
2939 | kfree(rxd); | ||
2940 | } | ||
2927 | 2941 | ||
2928 | macsec_del_dev(macsec); | 2942 | macsec_del_dev(macsec); |
2929 | } | 2943 | } |
@@ -2945,8 +2959,10 @@ static int register_macsec_dev(struct net_device *real_dev, | |||
2945 | 2959 | ||
2946 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, | 2960 | err = netdev_rx_handler_register(real_dev, macsec_handle_frame, |
2947 | rxd); | 2961 | rxd); |
2948 | if (err < 0) | 2962 | if (err < 0) { |
2963 | kfree(rxd); | ||
2949 | return err; | 2964 | return err; |
2965 | } | ||
2950 | } | 2966 | } |
2951 | 2967 | ||
2952 | list_add_tail_rcu(&macsec->secys, &rxd->secys); | 2968 | list_add_tail_rcu(&macsec->secys, &rxd->secys); |
@@ -3066,6 +3082,8 @@ static int macsec_newlink(struct net *net, struct net_device *dev, | |||
3066 | if (err < 0) | 3082 | if (err < 0) |
3067 | goto del_dev; | 3083 | goto del_dev; |
3068 | 3084 | ||
3085 | macsec_generation++; | ||
3086 | |||
3069 | dev_hold(real_dev); | 3087 | dev_hold(real_dev); |
3070 | 3088 | ||
3071 | return 0; | 3089 | return 0; |
@@ -3079,7 +3097,7 @@ unregister: | |||
3079 | 3097 | ||
3080 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | 3098 | static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) |
3081 | { | 3099 | { |
3082 | u64 csid = DEFAULT_CIPHER_ID; | 3100 | u64 csid = MACSEC_DEFAULT_CIPHER_ID; |
3083 | u8 icv_len = DEFAULT_ICV_LEN; | 3101 | u8 icv_len = DEFAULT_ICV_LEN; |
3084 | int flag; | 3102 | int flag; |
3085 | bool es, scb, sci; | 3103 | bool es, scb, sci; |
@@ -3094,8 +3112,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
3094 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); | 3112 | icv_len = nla_get_u8(data[IFLA_MACSEC_ICV_LEN]); |
3095 | 3113 | ||
3096 | switch (csid) { | 3114 | switch (csid) { |
3097 | case DEFAULT_CIPHER_ID: | 3115 | case MACSEC_DEFAULT_CIPHER_ID: |
3098 | case DEFAULT_CIPHER_ALT: | 3116 | case MACSEC_DEFAULT_CIPHER_ALT: |
3099 | if (icv_len < MACSEC_MIN_ICV_LEN || | 3117 | if (icv_len < MACSEC_MIN_ICV_LEN || |
3100 | icv_len > MACSEC_MAX_ICV_LEN) | 3118 | icv_len > MACSEC_MAX_ICV_LEN) |
3101 | return -EINVAL; | 3119 | return -EINVAL; |
@@ -3129,8 +3147,8 @@ static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) | |||
3129 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) | 3147 | nla_get_u8(data[IFLA_MACSEC_VALIDATION]) > MACSEC_VALIDATE_MAX) |
3130 | return -EINVAL; | 3148 | return -EINVAL; |
3131 | 3149 | ||
3132 | if ((data[IFLA_MACSEC_PROTECT] && | 3150 | if ((data[IFLA_MACSEC_REPLAY_PROTECT] && |
3133 | nla_get_u8(data[IFLA_MACSEC_PROTECT])) && | 3151 | nla_get_u8(data[IFLA_MACSEC_REPLAY_PROTECT])) && |
3134 | !data[IFLA_MACSEC_WINDOW]) | 3152 | !data[IFLA_MACSEC_WINDOW]) |
3135 | return -EINVAL; | 3153 | return -EINVAL; |
3136 | 3154 | ||
@@ -3168,7 +3186,8 @@ static int macsec_fill_info(struct sk_buff *skb, | |||
3168 | 3186 | ||
3169 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || | 3187 | if (nla_put_sci(skb, IFLA_MACSEC_SCI, secy->sci) || |
3170 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || | 3188 | nla_put_u8(skb, IFLA_MACSEC_ICV_LEN, secy->icv_len) || |
3171 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, DEFAULT_CIPHER_ID) || | 3189 | nla_put_u64(skb, IFLA_MACSEC_CIPHER_SUITE, |
3190 | MACSEC_DEFAULT_CIPHER_ID) || | ||
3172 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || | 3191 | nla_put_u8(skb, IFLA_MACSEC_ENCODING_SA, tx_sc->encoding_sa) || |
3173 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || | 3192 | nla_put_u8(skb, IFLA_MACSEC_ENCRYPT, tx_sc->encrypt) || |
3174 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || | 3193 | nla_put_u8(skb, IFLA_MACSEC_PROTECT, secy->protect_frames) || |