Ondrej Zajicek wrote:
On Thu, Jan 19, 2012 at 03:34:30PM +0400, Alexander V. Chernikov wrote:
So you removed it? Or renamed? I removed it, so another interface took it's interface id, but bird kept associating previous name (vlan's) with this id. - renaming fails in principally the same way: bird keeps previous name ;)
It is supposed to work (it is handled as removing and readding the interface), but probably not tested. Well, I was supposed to be awfully rich by now, but it wasn't tested, hence it didn't work :> Attached patch seems to work on FreeBSD. For OpenBSD rtsock events seems to be the same (and interface renaming is not supported there at all). I don't have any NetBSD instance to test on, unfortunately
Patch is not finished: interface renaming has to be handled in appropriate protocols. In OSPF, for example, it is a bit tricky due to the fact that interface can belong to several areas
I guess that seamless renaming is not really important, so it could be handled just by IF_CHANGE_TOO_MUCH (i.e. virtual iface down and up), that would work for any protocol. (or, because ifaces in BIRD are generally keyed by name, just remove the old one before creating the new one) BTW, AFAIK Linux does not allow iface renaming unless the iface is down. I've already got some rename-handling code in OSPF but it is not fully tested.. Maybe it is really better not to bother about keeping interface UP.
struct_iface should not be freed when interface disappears. There are users for that (most recently link-local sticky neighbors, but AFAIK there are others i don't remember now). Perhaps these structures should So the right way is to change such users behavior ? We definitely know interface is destroyed by OS and we can't predict if it ever comes up again and name / iface index / addresses are the same. Moreover, imagine bird running on some kind of PPTP server with several thousand interface UP which are destroyed/created with different interface indexes, names and addreses with the rate of several interfaces per second. (and bird announce all such interfaces (which has public/32 aadresses via OSPF) - this is typical configuration for PPTP/PPPOE server farm). This is, of course, not very similar to RS usage pattern, but bird claims to be 'sully functional dynamic IP routing daemon', right? :)
For NEF_STICKY we can either set iface pointer to NULL (and teach neighbor-api consumers to check this, which is fair) or simply get some gloval static "DUMMY" interface structure and change interface pointer to it.
be reference counted, but keeping them with IF_SHUTDOWN is OK. One thing that was a cause for a bug related to renaming is that shutdown ifaces kept their iface index and are returned by if_find_by_index(). Simple fix for that would probably make destroying and creating ifaces work.
RTM_IFANNOUNCE seems useful. Am i understand that correctly that any iface changes are notified using RTM_IFINFO, just create and destroy of ifaces are notified using RTM_IFANNOUNCE? And also that when newly
Yes. This is stated in route(4): #define RTM_IFINFO 0xe /* iface going up/down etc. */ #define RTM_IFANNOUNCE 0x11 /* iface arrival/departure */ To be more precise: ifconfig vlan999 create inet 1.2.3.4/29 triggers the following: got message of size 24 on Sun Jan 22 17:11:43 2012 RTM_IFANNOUNCE: interface arrival/departure: len 24, if# 15, what: arrival got message of size 184 on Sun Jan 22 17:11:43 2012 RTM_DELETE: Delete Route: len 184, pid: 0, seq 0, errno 0, flags:<UP,GATEWAY,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> default default default got message of size 108 on Sun Jan 22 17:11:43 2012 RTM_DELADDR: address being removed from iface: len 108, metric 0, flags: sockaddrs: <NETMASK,IFP,IFA,BRD> default vlan999:0.0.0.0.0.0 default default got message of size 116 on Sun Jan 22 17:11:43 2012 RTM_NEWADDR: address being added to iface: len 116, metric 0, flags: sockaddrs: <NETMASK,IFP,IFA,BRD> 255.255.255.248 vlan999:0.0.0.0.0.0 1.2.3.4 1.2.3.7 got message of size 232 on Sun Jan 22 17:11:45 2012 RTM_ADD: Add Route: len 232, pid: 0, seq 0, errno 0, flags:<UP> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 1.2.3.0 (255) ffff ffff f8ff ... (multicast. ipv6, ipv6 mcast) Destroying interface gives nearly the same: got message of size 232 on Sun Jan 22 17:21:16 2012 RTM_DELETE: Delete Route: len 232, pid: 0, seq 0, errno 0, flags: locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> 1.2.3.0 (255) ffff ffff f8ff got message of size 116 on Sun Jan 22 17:21:16 2012 RTM_DELADDR: address being removed from iface: len 116, metric 0, flags:<UP,HOST> sockaddrs: <NETMASK,IFP,IFA,BRD> 255.255.255.248 vlan999:0.0.0.0.0.0 1.2.3.4 1.2.3.7 got message of size 168 on Sun Jan 22 17:21:16 2012 RTM_IFINFO: iface status change: len 168, if# 15, link: unknown, flags:<BROADCAST,MULTICAST> got message of size 192 on Sun Jan 22 17:21:16 2012 RTM_DELETE: Delete Route: len 192, pid: 0, seq 0, errno 0, flags:<UP,GATEWAY,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> default 1.2.3.4 default got message of size 116 on Sun Jan 22 17:21:16 2012 RTM_DELADDR: address being removed from iface: len 116, metric 0, flags: sockaddrs: <NETMASK,IFP,IFA,BRD> 255.255.255.248 vlan999:0.0.0.0.0.0 1.2.3.4 1.2.3.7 got message of size 272 on Sun Jan 22 17:21:16 2012 RTM_DELETE: Delete Route: len 272, pid: 0, seq 0, errno 0, flags:<HOST,STATIC> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK> fe80::beae:c5ff:fe2e:4d74%15 0.0.0.0.0.0 ffff:ffff:ffff:ffff:: got message of size 140 on Sun Jan 22 17:21:16 2012 RTM_DELADDR: address being removed from iface: len 140, metric 0, flags: sockaddrs: <NETMASK,IFP,IFA> ffff:ffff:ffff:ffff:: vlan999:0.0.0.0.0.0 fe80::beae:c5ff:fe2e:4d74%15 got message of size 344 on Sun Jan 22 17:21:16 2012 RTM_DELETE: Delete Route: len 344, pid: 0, seq 0, errno 0, flags:<DONE> locks: inits: sockaddrs: <DST,GATEWAY,NETMASK,IFP,IFA> fe80::%15 (255) ffff ffff ffff ffff ffff ffff ffff vlan999:0.0.0.0.0.0 fe80::beae:c5ff:fe2e:4d74%15 got message of size 24 on Sun Jan 22 17:21:16 2012 RTM_IFANNOUNCE: interface arrival/departure: len 24, if# 15, what: departure OpenBSD and NetBSD behaves the same way (ordering of IF_ANNOUNCE / IF_IFINFO / RTM_ADD / RTM_DEL is the same)
created iface is announced by RTM_IFANNOUNCE, there is almost none information in that announcement to really create the iface in BIRD? Perhaps it is supposed to request RTM_IFINFO about that iface by some sysctl? Or we could at least trigger early iface scan. Well, we can simply listen to the next routing socket messages (or really trigger iface scan as a quick fix)
Some other comments below.
+ /* Interface is renamed. */ + if (strcmp(iface->name, ifam->ifan_name)) + { + DBG("KRT: Interface %s renamed to %s\n", iface->name, ifam->ifan_name); + memcpy(&f, iface, sizeof(struct iface)); + /* Assume both strings are IFNAMSIZ length */ + memcpy(f.name, ifam->ifan_name, IFNAMSIZ); + if_update(&f); + }
This does not work well. Because if_update would match iface by name, this would create a new iface structure so there would be two, until the old one would be removed during another iface scan. As a consequence, if_what_changed() would never return IF_CHANGE_NAME. Already notices that, thanks.
@@ -588,6 +642,8 @@ krt_read_msg(struct proto *p, struct ks_msg *msg, int scan) case RTM_DELETE: krt_read_rt(msg, (struct krt_proto *)p, scan); break; + case RTM_IFANNOUNCE: + krt_read_ifannounce(msg); case RTM_IFINFO: krt_read_ifinfo(msg); break;
Missing break here? Yes.