aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/macsec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/macsec.c')
-rw-r--r--drivers/net/macsec.c65
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
2438nla_put_failure: 2442nla_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
2447static int macsec_generation = 1; /* protected by RTNL */
2448
2444static int macsec_dump_txsc(struct sk_buff *skb, struct netlink_callback *cb) 2449static 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
2469done: 2478done:
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
3080static int macsec_validate_attr(struct nlattr *tb[], struct nlattr *data[]) 3098static 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) ||