|
26 | 26 | #include <linux/ethtool.h> |
27 | 27 | #include <linux/phy.h> |
28 | 28 | #include <net/arp.h> |
| 29 | +#include <net/macsec.h> |
29 | 30 |
|
30 | 31 | #include "vlan.h" |
31 | 32 | #include "vlanproc.h" |
@@ -572,6 +573,9 @@ static int vlan_dev_init(struct net_device *dev) |
572 | 573 | NETIF_F_HIGHDMA | NETIF_F_SCTP_CRC | |
573 | 574 | NETIF_F_ALL_FCOE; |
574 | 575 |
|
| 576 | + if (real_dev->vlan_features & NETIF_F_HW_MACSEC) |
| 577 | + dev->hw_features |= NETIF_F_HW_MACSEC; |
| 578 | + |
575 | 579 | dev->features |= dev->hw_features | NETIF_F_LLTX; |
576 | 580 | netif_inherit_tso_max(dev, real_dev); |
577 | 581 | if (dev->features & NETIF_F_VLAN_FEATURES) |
@@ -803,6 +807,241 @@ static int vlan_dev_fill_forward_path(struct net_device_path_ctx *ctx, |
803 | 807 | return 0; |
804 | 808 | } |
805 | 809 |
|
| 810 | +#if IS_ENABLED(CONFIG_MACSEC) |
| 811 | + |
| 812 | +static const struct macsec_ops *vlan_get_macsec_ops(const struct macsec_context *ctx) |
| 813 | +{ |
| 814 | + return vlan_dev_priv(ctx->netdev)->real_dev->macsec_ops; |
| 815 | +} |
| 816 | + |
| 817 | +static int vlan_macsec_offload(int (* const func)(struct macsec_context *), |
| 818 | + struct macsec_context *ctx) |
| 819 | +{ |
| 820 | + if (unlikely(!func)) |
| 821 | + return 0; |
| 822 | + |
| 823 | + return (*func)(ctx); |
| 824 | +} |
| 825 | + |
| 826 | +static int vlan_macsec_dev_open(struct macsec_context *ctx) |
| 827 | +{ |
| 828 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 829 | + |
| 830 | + if (!ops) |
| 831 | + return -EOPNOTSUPP; |
| 832 | + |
| 833 | + return vlan_macsec_offload(ops->mdo_dev_open, ctx); |
| 834 | +} |
| 835 | + |
| 836 | +static int vlan_macsec_dev_stop(struct macsec_context *ctx) |
| 837 | +{ |
| 838 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 839 | + |
| 840 | + if (!ops) |
| 841 | + return -EOPNOTSUPP; |
| 842 | + |
| 843 | + return vlan_macsec_offload(ops->mdo_dev_stop, ctx); |
| 844 | +} |
| 845 | + |
| 846 | +static int vlan_macsec_add_secy(struct macsec_context *ctx) |
| 847 | +{ |
| 848 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 849 | + |
| 850 | + if (!ops) |
| 851 | + return -EOPNOTSUPP; |
| 852 | + |
| 853 | + return vlan_macsec_offload(ops->mdo_add_secy, ctx); |
| 854 | +} |
| 855 | + |
| 856 | +static int vlan_macsec_upd_secy(struct macsec_context *ctx) |
| 857 | +{ |
| 858 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 859 | + |
| 860 | + if (!ops) |
| 861 | + return -EOPNOTSUPP; |
| 862 | + |
| 863 | + return vlan_macsec_offload(ops->mdo_upd_secy, ctx); |
| 864 | +} |
| 865 | + |
| 866 | +static int vlan_macsec_del_secy(struct macsec_context *ctx) |
| 867 | +{ |
| 868 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 869 | + |
| 870 | + if (!ops) |
| 871 | + return -EOPNOTSUPP; |
| 872 | + |
| 873 | + return vlan_macsec_offload(ops->mdo_del_secy, ctx); |
| 874 | +} |
| 875 | + |
| 876 | +static int vlan_macsec_add_rxsc(struct macsec_context *ctx) |
| 877 | +{ |
| 878 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 879 | + |
| 880 | + if (!ops) |
| 881 | + return -EOPNOTSUPP; |
| 882 | + |
| 883 | + return vlan_macsec_offload(ops->mdo_add_rxsc, ctx); |
| 884 | +} |
| 885 | + |
| 886 | +static int vlan_macsec_upd_rxsc(struct macsec_context *ctx) |
| 887 | +{ |
| 888 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 889 | + |
| 890 | + if (!ops) |
| 891 | + return -EOPNOTSUPP; |
| 892 | + |
| 893 | + return vlan_macsec_offload(ops->mdo_upd_rxsc, ctx); |
| 894 | +} |
| 895 | + |
| 896 | +static int vlan_macsec_del_rxsc(struct macsec_context *ctx) |
| 897 | +{ |
| 898 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 899 | + |
| 900 | + if (!ops) |
| 901 | + return -EOPNOTSUPP; |
| 902 | + |
| 903 | + return vlan_macsec_offload(ops->mdo_del_rxsc, ctx); |
| 904 | +} |
| 905 | + |
| 906 | +static int vlan_macsec_add_rxsa(struct macsec_context *ctx) |
| 907 | +{ |
| 908 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 909 | + |
| 910 | + if (!ops) |
| 911 | + return -EOPNOTSUPP; |
| 912 | + |
| 913 | + return vlan_macsec_offload(ops->mdo_add_rxsa, ctx); |
| 914 | +} |
| 915 | + |
| 916 | +static int vlan_macsec_upd_rxsa(struct macsec_context *ctx) |
| 917 | +{ |
| 918 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 919 | + |
| 920 | + if (!ops) |
| 921 | + return -EOPNOTSUPP; |
| 922 | + |
| 923 | + return vlan_macsec_offload(ops->mdo_upd_rxsa, ctx); |
| 924 | +} |
| 925 | + |
| 926 | +static int vlan_macsec_del_rxsa(struct macsec_context *ctx) |
| 927 | +{ |
| 928 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 929 | + |
| 930 | + if (!ops) |
| 931 | + return -EOPNOTSUPP; |
| 932 | + |
| 933 | + return vlan_macsec_offload(ops->mdo_del_rxsa, ctx); |
| 934 | +} |
| 935 | + |
| 936 | +static int vlan_macsec_add_txsa(struct macsec_context *ctx) |
| 937 | +{ |
| 938 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 939 | + |
| 940 | + if (!ops) |
| 941 | + return -EOPNOTSUPP; |
| 942 | + |
| 943 | + return vlan_macsec_offload(ops->mdo_add_txsa, ctx); |
| 944 | +} |
| 945 | + |
| 946 | +static int vlan_macsec_upd_txsa(struct macsec_context *ctx) |
| 947 | +{ |
| 948 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 949 | + |
| 950 | + if (!ops) |
| 951 | + return -EOPNOTSUPP; |
| 952 | + |
| 953 | + return vlan_macsec_offload(ops->mdo_upd_txsa, ctx); |
| 954 | +} |
| 955 | + |
| 956 | +static int vlan_macsec_del_txsa(struct macsec_context *ctx) |
| 957 | +{ |
| 958 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 959 | + |
| 960 | + if (!ops) |
| 961 | + return -EOPNOTSUPP; |
| 962 | + |
| 963 | + return vlan_macsec_offload(ops->mdo_del_txsa, ctx); |
| 964 | +} |
| 965 | + |
| 966 | +static int vlan_macsec_get_dev_stats(struct macsec_context *ctx) |
| 967 | +{ |
| 968 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 969 | + |
| 970 | + if (!ops) |
| 971 | + return -EOPNOTSUPP; |
| 972 | + |
| 973 | + return vlan_macsec_offload(ops->mdo_get_dev_stats, ctx); |
| 974 | +} |
| 975 | + |
| 976 | +static int vlan_macsec_get_tx_sc_stats(struct macsec_context *ctx) |
| 977 | +{ |
| 978 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 979 | + |
| 980 | + if (!ops) |
| 981 | + return -EOPNOTSUPP; |
| 982 | + |
| 983 | + return vlan_macsec_offload(ops->mdo_get_tx_sc_stats, ctx); |
| 984 | +} |
| 985 | + |
| 986 | +static int vlan_macsec_get_tx_sa_stats(struct macsec_context *ctx) |
| 987 | +{ |
| 988 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 989 | + |
| 990 | + if (!ops) |
| 991 | + return -EOPNOTSUPP; |
| 992 | + |
| 993 | + return vlan_macsec_offload(ops->mdo_get_tx_sa_stats, ctx); |
| 994 | +} |
| 995 | + |
| 996 | +static int vlan_macsec_get_rx_sc_stats(struct macsec_context *ctx) |
| 997 | +{ |
| 998 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 999 | + |
| 1000 | + if (!ops) |
| 1001 | + return -EOPNOTSUPP; |
| 1002 | + |
| 1003 | + return vlan_macsec_offload(ops->mdo_get_rx_sc_stats, ctx); |
| 1004 | +} |
| 1005 | + |
| 1006 | +static int vlan_macsec_get_rx_sa_stats(struct macsec_context *ctx) |
| 1007 | +{ |
| 1008 | + const struct macsec_ops *ops = vlan_get_macsec_ops(ctx); |
| 1009 | + |
| 1010 | + if (!ops) |
| 1011 | + return -EOPNOTSUPP; |
| 1012 | + |
| 1013 | + return vlan_macsec_offload(ops->mdo_get_rx_sa_stats, ctx); |
| 1014 | +} |
| 1015 | + |
| 1016 | +static const struct macsec_ops macsec_offload_ops = { |
| 1017 | + /* Device wide */ |
| 1018 | + .mdo_dev_open = vlan_macsec_dev_open, |
| 1019 | + .mdo_dev_stop = vlan_macsec_dev_stop, |
| 1020 | + /* SecY */ |
| 1021 | + .mdo_add_secy = vlan_macsec_add_secy, |
| 1022 | + .mdo_upd_secy = vlan_macsec_upd_secy, |
| 1023 | + .mdo_del_secy = vlan_macsec_del_secy, |
| 1024 | + /* Security channels */ |
| 1025 | + .mdo_add_rxsc = vlan_macsec_add_rxsc, |
| 1026 | + .mdo_upd_rxsc = vlan_macsec_upd_rxsc, |
| 1027 | + .mdo_del_rxsc = vlan_macsec_del_rxsc, |
| 1028 | + /* Security associations */ |
| 1029 | + .mdo_add_rxsa = vlan_macsec_add_rxsa, |
| 1030 | + .mdo_upd_rxsa = vlan_macsec_upd_rxsa, |
| 1031 | + .mdo_del_rxsa = vlan_macsec_del_rxsa, |
| 1032 | + .mdo_add_txsa = vlan_macsec_add_txsa, |
| 1033 | + .mdo_upd_txsa = vlan_macsec_upd_txsa, |
| 1034 | + .mdo_del_txsa = vlan_macsec_del_txsa, |
| 1035 | + /* Statistics */ |
| 1036 | + .mdo_get_dev_stats = vlan_macsec_get_dev_stats, |
| 1037 | + .mdo_get_tx_sc_stats = vlan_macsec_get_tx_sc_stats, |
| 1038 | + .mdo_get_tx_sa_stats = vlan_macsec_get_tx_sa_stats, |
| 1039 | + .mdo_get_rx_sc_stats = vlan_macsec_get_rx_sc_stats, |
| 1040 | + .mdo_get_rx_sa_stats = vlan_macsec_get_rx_sa_stats, |
| 1041 | +}; |
| 1042 | + |
| 1043 | +#endif |
| 1044 | + |
806 | 1045 | static const struct ethtool_ops vlan_ethtool_ops = { |
807 | 1046 | .get_link_ksettings = vlan_ethtool_get_link_ksettings, |
808 | 1047 | .get_drvinfo = vlan_ethtool_get_drvinfo, |
@@ -869,6 +1108,9 @@ void vlan_setup(struct net_device *dev) |
869 | 1108 | dev->priv_destructor = vlan_dev_free; |
870 | 1109 | dev->ethtool_ops = &vlan_ethtool_ops; |
871 | 1110 |
|
| 1111 | +#if IS_ENABLED(CONFIG_MACSEC) |
| 1112 | + dev->macsec_ops = &macsec_offload_ops; |
| 1113 | +#endif |
872 | 1114 | dev->min_mtu = 0; |
873 | 1115 | dev->max_mtu = ETH_MAX_MTU; |
874 | 1116 |
|
|
0 commit comments