35 #include <sys/modctl.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/atomic.h>
39 #include <sys/stat.h>
40 #include <sys/modhash.h>
41 #include <sys/strsubr.h>
42 #include <sys/strsun.h>
43 #include <sys/dlpi.h>
44 #include <sys/mac.h>
45 #include <sys/mac_provider.h>
46 #include <sys/mac_client.h>
47 #include <sys/mac_client_priv.h>
48 #include <sys/mac_ether.h>
49 #include <sys/dls.h>
50 #include <sys/pattr.h>
51 #include <sys/time.h>
52 #include <sys/vlan.h>
53 #include <sys/vnic.h>
54 #include <sys/vnic_impl.h>
55 #include <sys/mac_flow_impl.h>
56 #include <inet/ip_impl.h>
57
58 /*
59 * Note that for best performance, the VNIC is a passthrough design.
60 * For each VNIC corresponds a MAC client of the underlying MAC (lower MAC).
61 * This MAC client is opened by the VNIC driver at VNIC creation,
62 * and closed when the VNIC is deleted.
63 * When a MAC client of the VNIC itself opens a VNIC, the MAC layer
64 * (upper MAC) detects that the MAC being opened is a VNIC. Instead
65 * of allocating a new MAC client, it asks the VNIC driver to return
66 * the lower MAC client handle associated with the VNIC, and that handle
67 * is returned to the upper MAC client directly. This allows access
68 * by upper MAC clients of the VNIC to have direct access to the lower
69 * MAC client for the control path and data path.
70 *
71 * Due to this passthrough, some of the entry points exported by the
72 * VNIC driver are never directly invoked. These entry points include
73 * vnic_m_start, vnic_m_stop, vnic_m_promisc, vnic_m_multicst, etc.
74 */
830 {
831 return (0);
832 }
833
834 static int
835 vnic_m_unicst(void *arg, const uint8_t *macaddr)
836 {
837 vnic_t *vnic = arg;
838
839 return (mac_vnic_unicast_set(vnic->vn_mch, macaddr));
840 }
841
842 /*
843 * Callback functions for set/get of properties
844 */
845 /*ARGSUSED*/
846 static int
847 vnic_m_setprop(void *m_driver, const char *pr_name, mac_prop_id_t pr_num,
848 uint_t pr_valsize, const void *pr_val)
849 {
850 int err = ENOTSUP;
851 vnic_t *vn = m_driver;
852
853 switch (pr_num) {
854 case MAC_PROP_MTU: {
855 uint32_t mtu;
856
857 /* allow setting MTU only on an etherstub */
858 if (vn->vn_link_id != DATALINK_INVALID_LINKID)
859 return (err);
860
861 if (pr_valsize < sizeof (mtu)) {
862 err = EINVAL;
863 break;
864 }
865 bcopy(pr_val, &mtu, sizeof (mtu));
866 if (mtu < ANCHOR_VNIC_MIN_MTU || mtu > ANCHOR_VNIC_MAX_MTU) {
867 err = EINVAL;
868 break;
869 }
870 err = mac_maxsdu_update(vn->vn_mh, mtu);
871 break;
872 }
873 case MAC_PROP_VN_PROMISC_FILTERED: {
874 boolean_t filtered;
875
876 if (pr_valsize < sizeof (filtered)) {
877 err = EINVAL;
878 break;
879 }
880
881 bcopy(pr_val, &filtered, sizeof (filtered));
882 err = mac_set_promisc_filtered(vn->vn_mch, filtered);
883 }
884 default:
885 break;
886 }
887 return (err);
888 }
889
890 static int
891 vnic_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
892 uint_t pr_valsize, void *pr_val)
893 {
894 vnic_t *vn = arg;
895 int ret = 0;
896 boolean_t out;
897
898 switch (pr_num) {
899 case MAC_PROP_VN_PROMISC_FILTERED:
900 out = mac_get_promisc_filtered(vn->vn_mch);
901 ASSERT(pr_valsize >= sizeof (boolean_t));
902 bcopy(&out, pr_val, sizeof (boolean_t));
903 break;
904 default:
|
35 #include <sys/modctl.h>
36 #include <sys/ddi.h>
37 #include <sys/sunddi.h>
38 #include <sys/atomic.h>
39 #include <sys/stat.h>
40 #include <sys/modhash.h>
41 #include <sys/strsubr.h>
42 #include <sys/strsun.h>
43 #include <sys/dlpi.h>
44 #include <sys/mac.h>
45 #include <sys/mac_provider.h>
46 #include <sys/mac_client.h>
47 #include <sys/mac_client_priv.h>
48 #include <sys/mac_ether.h>
49 #include <sys/dls.h>
50 #include <sys/pattr.h>
51 #include <sys/time.h>
52 #include <sys/vlan.h>
53 #include <sys/vnic.h>
54 #include <sys/vnic_impl.h>
55 #include <sys/mac_impl.h>
56 #include <sys/mac_flow_impl.h>
57 #include <inet/ip_impl.h>
58
59 /*
60 * Note that for best performance, the VNIC is a passthrough design.
61 * For each VNIC corresponds a MAC client of the underlying MAC (lower MAC).
62 * This MAC client is opened by the VNIC driver at VNIC creation,
63 * and closed when the VNIC is deleted.
64 * When a MAC client of the VNIC itself opens a VNIC, the MAC layer
65 * (upper MAC) detects that the MAC being opened is a VNIC. Instead
66 * of allocating a new MAC client, it asks the VNIC driver to return
67 * the lower MAC client handle associated with the VNIC, and that handle
68 * is returned to the upper MAC client directly. This allows access
69 * by upper MAC clients of the VNIC to have direct access to the lower
70 * MAC client for the control path and data path.
71 *
72 * Due to this passthrough, some of the entry points exported by the
73 * VNIC driver are never directly invoked. These entry points include
74 * vnic_m_start, vnic_m_stop, vnic_m_promisc, vnic_m_multicst, etc.
75 */
831 {
832 return (0);
833 }
834
835 static int
836 vnic_m_unicst(void *arg, const uint8_t *macaddr)
837 {
838 vnic_t *vnic = arg;
839
840 return (mac_vnic_unicast_set(vnic->vn_mch, macaddr));
841 }
842
843 /*
844 * Callback functions for set/get of properties
845 */
846 /*ARGSUSED*/
847 static int
848 vnic_m_setprop(void *m_driver, const char *pr_name, mac_prop_id_t pr_num,
849 uint_t pr_valsize, const void *pr_val)
850 {
851 int err = 0;
852 vnic_t *vn = m_driver;
853
854 switch (pr_num) {
855 case MAC_PROP_MTU: {
856 uint32_t mtu;
857
858 /* allow setting MTU only on an etherstub */
859 if (vn->vn_link_id != DATALINK_INVALID_LINKID) {
860 err = ENOTSUP;
861 break;
862 }
863
864 if (pr_valsize < sizeof (mtu)) {
865 err = EINVAL;
866 break;
867 }
868 bcopy(pr_val, &mtu, sizeof (mtu));
869 if (mtu < ANCHOR_VNIC_MIN_MTU || mtu > ANCHOR_VNIC_MAX_MTU) {
870 err = EINVAL;
871 break;
872 }
873 err = mac_maxsdu_update(vn->vn_mh, mtu);
874 break;
875 }
876 case MAC_PROP_VN_PROMISC_FILTERED: {
877 boolean_t filtered;
878
879 if (pr_valsize < sizeof (filtered)) {
880 err = EINVAL;
881 break;
882 }
883
884 bcopy(pr_val, &filtered, sizeof (filtered));
885 mac_set_promisc_filtered(vn->vn_mch, filtered);
886 }
887 default:
888 err = ENOTSUP;
889 break;
890 }
891 return (err);
892 }
893
894 static int
895 vnic_m_getprop(void *arg, const char *pr_name, mac_prop_id_t pr_num,
896 uint_t pr_valsize, void *pr_val)
897 {
898 vnic_t *vn = arg;
899 int ret = 0;
900 boolean_t out;
901
902 switch (pr_num) {
903 case MAC_PROP_VN_PROMISC_FILTERED:
904 out = mac_get_promisc_filtered(vn->vn_mch);
905 ASSERT(pr_valsize >= sizeof (boolean_t));
906 bcopy(&out, pr_val, sizeof (boolean_t));
907 break;
908 default:
|