| Summary: | ifconfig(8): the setifmediacallback function is not returning the saved media data before making the ioctl call | ||
|---|---|---|---|
| Product: | Base System | Reporter: | Spencer Minear <minear> |
| Component: | bin | Assignee: | Doug Ambrisko <ambrisko> |
| Status: | Closed FIXED | ||
| Severity: | Affects Only Me | ||
| Priority: | Normal | ||
| Version: | Unspecified | ||
| Hardware: | Any | ||
| OS: | Any | ||
Responsible Changed From-To: freebsd-bugs->ambrisko Looks like Doug's change has introduced this. State Changed From-To: open->closed You were right. It's been a while since I worked in this. Yes I forgot to put the modified value into the global structure. I probably thought ifmr and ifr were the same :-( Thanks for the fix. |
The 1.19 version of ifconfig/ifmedia.c added the use of setifmediacallback so that media setting gets done only once at the end of the sequence of changes. The change carefully made sure the that new media value was saved in the ifmr structure which is held in the callback structure. However the new setifmediacallback structure fails to return media information saved in the ifmr structure to the ifr structure before the ioctl call is made. This depending on the order of parameters on the ifconfig command this can result in making a SIOCSIFMEDIA call with parameters from a previous operation. Fix: I think the fix is simple. Add ifr.ifr_media = ifmr->ifm_current; following line 242. The code should look like: if (!did_it) { ifr.ifr_media = ifmr->ifm_current; if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0) It isn't quite this simple since that will nuke the media setting. The problem appears to be the SIOCSIFMEDIA is not just looking at the media settings like it should ... it should ignore the other attributes. I agree this is a side-effect of my change since before everything was banged into the NIC one at a time which caused its own problems when the media didn't really changed but it forced the NIC to change it. This requires more digging to see if this is a problem in the ifmedia ioctl to prevent gross hacking of ifconfig. How-To-Repeat: Use a command like: ifconfig <IF> inet <addr> netmask <mask> media <mediasetting> mtu 1500 In this case the mtu ioctl gets done before the media ioctl. In this case the medial ioctl call contains the 1500 left over from the mtu ioctl call and returns an ENXIO error.