| 1030 | } |
| 1031 | |
| 1032 | int |
| 1033 | ff_rtioctl(int fibnum, void *data, unsigned *plen, unsigned maxlen) |
| 1034 | { |
| 1035 | struct rt_msghdr *rtm = NULL; |
| 1036 | struct rtentry *rt = NULL; |
| 1037 | struct rt_addrinfo info; |
| 1038 | struct epoch_tracker et; |
| 1039 | #ifdef INET6 |
| 1040 | struct sockaddr_storage ss; |
| 1041 | struct sockaddr_in6 *sin6; |
| 1042 | int i, rti_need_deembed = 0; |
| 1043 | #endif |
| 1044 | int alloc_len = 0, len, error = 0; |
| 1045 | sa_family_t saf = AF_UNSPEC; |
| 1046 | struct rib_cmd_info rc; |
| 1047 | struct nhop_object *nh; |
| 1048 | |
| 1049 | #define senderr(e) { error = e; goto flush;} |
| 1050 | |
| 1051 | len = *plen; |
| 1052 | |
| 1053 | /* |
| 1054 | * Most of current messages are in range 200-240 bytes, |
| 1055 | * minimize possible re-allocation on reply using larger size |
| 1056 | * buffer aligned on 1k boundaty. |
| 1057 | */ |
| 1058 | alloc_len = roundup2(len, 1024); |
| 1059 | if ((rtm = malloc(alloc_len, M_TEMP, M_NOWAIT)) == NULL) |
| 1060 | senderr(ENOBUFS); |
| 1061 | |
| 1062 | bcopy(data, (caddr_t)rtm, len); |
| 1063 | |
| 1064 | if (len < sizeof(*rtm) || len != rtm->rtm_msglen) |
| 1065 | senderr(EINVAL); |
| 1066 | |
| 1067 | bzero(&info, sizeof(info)); |
| 1068 | nh = NULL; |
| 1069 | |
| 1070 | if (rtm->rtm_version != RTM_VERSION) { |
| 1071 | /* Do not touch message since format is unknown */ |
| 1072 | free(rtm, M_TEMP); |
| 1073 | rtm = NULL; |
| 1074 | senderr(EPROTONOSUPPORT); |
| 1075 | } |
| 1076 | |
| 1077 | /* |
| 1078 | * Starting from here, it is possible |
| 1079 | * to alter original message and insert |
| 1080 | * caller PID and error value. |
| 1081 | */ |
| 1082 | |
| 1083 | if ((error = fill_addrinfo(rtm, len, fibnum, &info)) != 0) { |
| 1084 | senderr(error); |
| 1085 | } |
| 1086 | |
| 1087 | saf = info.rti_info[RTAX_DST]->sa_family; |
| 1088 | |
| 1089 | /* support for new ARP code */ |
no test coverage detected