| 999 | } |
| 1000 | |
| 1001 | static int |
| 1002 | lagg_port_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) |
| 1003 | { |
| 1004 | struct epoch_tracker et; |
| 1005 | struct lagg_reqport *rp = (struct lagg_reqport *)data; |
| 1006 | struct lagg_softc *sc; |
| 1007 | struct lagg_port *lp = NULL; |
| 1008 | int error = 0; |
| 1009 | |
| 1010 | /* Should be checked by the caller */ |
| 1011 | switch (ifp->if_type) { |
| 1012 | case IFT_IEEE8023ADLAG: |
| 1013 | case IFT_INFINIBANDLAG: |
| 1014 | if ((lp = ifp->if_lagg) == NULL || (sc = lp->lp_softc) == NULL) |
| 1015 | goto fallback; |
| 1016 | break; |
| 1017 | default: |
| 1018 | goto fallback; |
| 1019 | } |
| 1020 | |
| 1021 | switch (cmd) { |
| 1022 | case SIOCGLAGGPORT: |
| 1023 | if (rp->rp_portname[0] == '\0' || |
| 1024 | ifunit(rp->rp_portname) != ifp) { |
| 1025 | error = EINVAL; |
| 1026 | break; |
| 1027 | } |
| 1028 | |
| 1029 | NET_EPOCH_ENTER(et); |
| 1030 | if ((lp = ifp->if_lagg) == NULL || lp->lp_softc != sc) { |
| 1031 | error = ENOENT; |
| 1032 | NET_EPOCH_EXIT(et); |
| 1033 | break; |
| 1034 | } |
| 1035 | |
| 1036 | lagg_port2req(lp, rp); |
| 1037 | NET_EPOCH_EXIT(et); |
| 1038 | break; |
| 1039 | |
| 1040 | case SIOCSIFCAP: |
| 1041 | if (lp->lp_ioctl == NULL) { |
| 1042 | error = EINVAL; |
| 1043 | break; |
| 1044 | } |
| 1045 | error = (*lp->lp_ioctl)(ifp, cmd, data); |
| 1046 | if (error) |
| 1047 | break; |
| 1048 | |
| 1049 | /* Update lagg interface capabilities */ |
| 1050 | LAGG_XLOCK(sc); |
| 1051 | lagg_capabilities(sc); |
| 1052 | LAGG_XUNLOCK(sc); |
| 1053 | VLAN_CAPABILITIES(sc->sc_ifp); |
| 1054 | break; |
| 1055 | |
| 1056 | case SIOCSIFMTU: |
| 1057 | /* Do not allow the MTU to be changed once joined */ |
| 1058 | error = EINVAL; |
nothing calls this directly
no test coverage detected