Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Good day. Sun, Mar 18, 2007 at 08:17:09AM +0300, Eygene Ryabinkin wrote: You're right, thanks for spotting the error. The corrected patch is attached. After some iterations with rik@ we came to a next version of an if_bridge.4 patch. Comments are welcome. -- Eygene --- if_bridge.4.origSun Mar 4 15:37:22 2007 +++ if_bridge.4 Tue Mar 27 18:25:52 2007 @@ -82,6 +82,13 @@ .Nm interface randomly chooses a link (MAC) address in the range reserved for locally administered addresses when it is created. +This address is guaranteed to be unique +.Em only +across all +.Nm if_bridge +interfaces on the local machine. +Thus you can theoretically have two +bridges on the different machines with the same link addresses. The address can be changed by assigning the desired link address using .Xr ifconfig 8 . .Pp @@ -219,9 +226,89 @@ so all packets are passed to the filter for processing. .Pp -Note that packets to and from the bridging host will be seen by the -filter on the interface with the appropriate address configured as well -as on the interface on which the packet arrives or departs. +The packets originating from the bridging host will be seen by +the filter on the interface that is looked up in the routing +table. +.Pp +The packets destined to the bridging host will be seen by the filter +on the interface with the MAC address equal to the packet's destination +MAC. There are situations when some of the bridge members are sharing +the same MAC address (for example the +.Xr if_vlan 4 +interfaces: they are currenly sharing the +MAC address of the parent physical interface). +It is not possible to distinguish between these interfaces using +their MAC address, excluding the case when the packet's destination +MAC address is equal to the MAC address of the interface on which +the packet was entered to the system. +In this case the filter will see the incoming packet on this +interface. +In all other cases the interface seen by the packet filter is chosen +from the list of bridge members with the same MAC address and the +result strongly depends on the member addition sequence and the +actual implementation of +.Nm if_bridge . +It is not recommended to rely on the order chosen by the current +.Nm if_bridge +implementation: it can be changed in the future. +.Pp +The previous paragraph is best illustrated with the following +pictures. Let +.Bl -bullet +.It +the MAC address of the incoming packet's destination is +.Nm nn:nn:nn:nn:nn:nn , +.It +the interface on which packet entered the system is +.Nm ifX , +.It +.Nm ifX +MAC address is +.Nm xx:xx:xx:xx:xx:xx , +.It +there are possibly other bridge members with the same MAC address +.Nm xx:xx:xx:xx:xx:xx , +.It +the bridge has more than one interface that are sharing the +same MAC address +.Nm yy:yy:yy:yy:yy:yy ; +we will call them +.Nm vlanY1 , +.Nm vlanY2 , +etc. +.El +.Pp +Then if the MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm xx:xx:xx:xx:xx:xx +then the filter will see the packet on the interface +.Nm ifX +no matter if there are any other bridge members carrying the same +MAC address. +But if the MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm yy:yy:yy:yy:yy:yy +then the interface that will be seen by the filter is one of the +.Nm vlanYn . +It is not possible to predict the name of the actual interface +without the knowledge of the system state and the +.Nm if_bridge +implementation details. +.Pp +This problem arises for any bridge members that are sharing the same +MAC address, not only to the +.Xr if_vlan 4 +ones: they we taken just as the example of such situation. +So if one wants the filter the locally destined packets based on +their interface name, one should be aware of this implication. +The described situation will appear at least on the filtering bridges +that are doing IP-forwarding; in some of such cases it is better +to assign the IP address only to the +.Nm if_bridge +interface and not to the bridge members. +But your mileage may vary. .Sh EXAMPLES The following when placed in the file .Pa /etc/rc.conf ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: Good day. Sun, Mar 18, 2007 at 08:17:09AM +0300, Eygene Ryabinkin wrote: You're right, thanks for spotting the error. The corrected patch is attached. After some iterations with rik@ we came to a next version of an if_bridge.4 patch. Comments are welcome. If there is no objections, I'll wait till the weekend and commit this patch to finally close the PR. Eygene what about the next patch for physically input filtration? I guess we need a separate PR and a thread here for it. rik ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Tue, Mar 27, 2007 at 10:20:40PM +0400, Roman Kurakin wrote: Eygene what about the next patch for physically input filtration? I guess we need a separate PR and a thread here for it. Yes, I will port it to the new if_bridge.c. The end of this week is a good estimate for the patching and testing timeline from my side. Will open a PR once the new patch will work for me. -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Good day. Tue, Mar 13, 2007 at 08:50:29AM +0300, Eygene Ryabinkin wrote: Sure. And that is why all switches that can bear the IP on their interfaces have distinct MACs for each interface or/and the only one interface can have the IP. And that is why I am going to add the paragraph to the if_bridge(4) describing the current situation and giving advice on the setting IP for the bridge members and the bridge itself. Will provide the patch in a day or two. OK, the patch to the if_bridge.4 is attached. It is rather lengthy, but I don't know how to make it clear with less amount of words. Comments are welcome. -- Eygene --- if_bridge.4.origSun Mar 4 15:37:22 2007 +++ if_bridge.4 Sat Mar 17 22:18:52 2007 @@ -219,9 +219,67 @@ so all packets are passed to the filter for processing. .Pp -Note that packets to and from the bridging host will be seen by the -filter on the interface with the appropriate address configured as well -as on the interface on which the packet arrives or departs. +The packets originating from the bridging host will be seen by +the filter on the interface that is looked up in the routing +table according to the packet destination address (not the MAC +address). +.Pp +The packets destined to the bridging host will be seen by the filter +on the interface with the MAC address equal to the packet's destination +MAC. Be prepated to the situation when some of the bridge members are sharing +the same MAC address (for example the +.Xr if_vlan 4 +interfaces: they are currenly sharing the +MAC address of the parent physical interface). It is not possible +to distinguish between these interfaces using their MAC address, +excluding the case when the packet's destination MAC address is +equal to the MAC address of the interface on which the packet was +entered to the system. In this case the filter will see the incoming +packet on this interface. In all other cases the interface seen +by the packet filter is almost randomly chosen from the list of +bridge members with the same MAC address. +.Pp +The previous paragraph is best illustrated with the following +pictures. Let the MAC address of the incoming packet's destination will be +.Nm nn:nn:nn:nn:nn:nn , +the interface on which packet entered the system is +.Nm vlanX +with the MAC address +.Nm xx:xx:xx:xx:xx:xx +and the bridge has more than one interface that are sharing the +same MAC address +.Nm yy:yy:yy:yy:yy:yy ; +we will call them +.Nm vlanY1 , +.Nm vlanY2 , +etc. Then if MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm xx:xx:xx:xx:xx:xx +then the filter will see the packet on the interface +.Nm vlanX +no matter if there are some other bridge members carrying the same +MAC address. But if the MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm yy:yy:yy:yy:yy:yy +then the interface that will be seen by the filter is some of the +.Nm vlanYn , +but it is not possible to know the name of the actual interface +without the knowledge of the system state and the +.Nm if_bridge +implementation details. +.Pp +This problem arises for any bridge members that are sharing the same +MAC address, not only to the +.Xr if_vlan 4 +ones: they we taken just as the example of such situation. So if one wants +the filter the locally destined packets based on their interface name, +he should be aware of this implication. Such situation will appear on the +filtering bridges that are doing IP-forwarding; in this case it is better +to assign the IP address only to the +.Nm if_bridge +interface and not to the bridge members. But your mileage may vary. .Sh EXAMPLES The following when placed in the file .Pa /etc/rc.conf ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Julian, good day. +.Pp +The packets destined to the bridging host will be seen by the filter +on the interface with the MAC address equal to the packet's destination +MAC. Be prepated to the situation when some of the bridge members are sharing prepated to ? prepared for? ??? You're right, thanks for spotting the error. The corrected patch is attached. -- Eygene --- if_bridge.4.origSun Mar 4 15:37:22 2007 +++ if_bridge.4 Sun Mar 18 08:13:53 2007 @@ -219,9 +219,67 @@ so all packets are passed to the filter for processing. .Pp -Note that packets to and from the bridging host will be seen by the -filter on the interface with the appropriate address configured as well -as on the interface on which the packet arrives or departs. +The packets originating from the bridging host will be seen by +the filter on the interface that is looked up in the routing +table according to the packet destination address (not the MAC +address). +.Pp +The packets destined to the bridging host will be seen by the filter +on the interface with the MAC address equal to the packet's destination +MAC. Be prepared for the situation when some of the bridge members are sharing +the same MAC address (for example the +.Xr if_vlan 4 +interfaces: they are currenly sharing the +MAC address of the parent physical interface). It is not possible +to distinguish between these interfaces using their MAC address, +excluding the case when the packet's destination MAC address is +equal to the MAC address of the interface on which the packet was +entered to the system. In this case the filter will see the incoming +packet on this interface. In all other cases the interface seen +by the packet filter is almost randomly chosen from the list of +bridge members with the same MAC address. +.Pp +The previous paragraph is best illustrated with the following +pictures. Let the MAC address of the incoming packet's destination will be +.Nm nn:nn:nn:nn:nn:nn , +the interface on which packet entered the system is +.Nm vlanX +with the MAC address +.Nm xx:xx:xx:xx:xx:xx +and the bridge has more than one interface that are sharing the +same MAC address +.Nm yy:yy:yy:yy:yy:yy ; +we will call them +.Nm vlanY1 , +.Nm vlanY2 , +etc. Then if MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm xx:xx:xx:xx:xx:xx +then the filter will see the packet on the interface +.Nm vlanX +no matter if there are some other bridge members carrying the same +MAC address. But if the MAC address +.Nm nn:nn:nn:nn:nn:nn +is equal to the +.Nm yy:yy:yy:yy:yy:yy +then the interface that will be seen by the filter is some of the +.Nm vlanYn , +but it is not possible to know the name of the actual interface +without the knowledge of the system state and the +.Nm if_bridge +implementation details. +.Pp +This problem arises for any bridge members that are sharing the same +MAC address, not only to the +.Xr if_vlan 4 +ones: they we taken just as the example of such situation. So if one wants +the filter the locally destined packets based on their interface name, +he should be aware of this implication. Such situation will appear on the +filtering bridges that are doing IP-forwarding; in this case it is better +to assign the IP address only to the +.Nm if_bridge +interface and not to the bridge members. But your mileage may vary. .Sh EXAMPLES The following when placed in the file .Pa /etc/rc.conf ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Here it is. I'll check it for compilation this evening and I hope Eygene will be able to put it in a production for testings. The system with 6.2 and this patch is living since yesterday. No problems were spotted. I will try to put this patch into another, busier system, but this will not be the same patch: my own one will be applied on top of it. So this will not be the clear testcase. -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: I tried to understand this, because Bruce already gave me a patch, but I am a bit stupid: I do not see how M_PROMISC that is cleared unconditionally before BRIDGE_INPUT will help us to identify the right interface. As I see now, the BRIDGE_INPUT is called once from if_ethersubr.c, once from if_gif.c and once from ng_ether.c: http://fxr.watson.org/fxr/ident?i=BRIDGE_INPUT So there is no distinct code paths that can allow BRIDGE_INPUT to modify its behaviour based on the M_PROMISC flag. But I feel that I am wrong in some place and missing some discuission on the M_PROMISC. Can anyone point me to the right place? In short: M_PROMISC exists to easily identify frames which were received promiscuously, to prevent infinite recursion, and to simplify code which needs to re-enter ether_input(). M_PROMISC is a flag introduced by NetBSD into their ethernet input path to deal with the case where an entity in the network stack needs to receive frames promiscuously, without necessarily passing those frames to the upper layers e.g. IPv4. It is not documented; the code is the documentation in this instance. It is cleared when an mbuf chain is passed to another entity which may consume the frame in that mbuf chain, in case the entity re-enters ether_input() with the same mbuf chain for local delivery (e.g. bridge, netgraph, vlan). I do not think M_PROMISC alone is sufficient to solve our architectural problems at Layer 2. So all the tangled if()s inside LIST_FOREACH() will be gone completely from bridge_input(). But we still need to see if we want to consume the packet by the bridge or it members or to do forwarding. Am I missing something? Correct. Just because a frame was received promiscuously, does not imply that the bridge will be the only consumer of that frame. I'm afraid there is a serious flaw in the very notion of such a logical interface. If it's true, we should start by admitting that the support for logical interfaces should be a side hack for compatibility, and not something that can live forever on the main code path. I agree with you. That is why I patched if_bridge once again to enable the pfil hooks for the physical incoming interface. And there are two ways to solve the problem: - to give each VLAN interface the distinct MAC, as Bruce suggested, I didn't suggest this. :-) I pointed out that the code matches on destination MAC only at the moment. vlan(4) is an abstraction of something which exists as part of the Ethernet framing, and is not a physical interface in its own right, as was correctly identified above. - to refuse the logical interfaces completely and to support only physical ones. It is what my very first (and very short) patch did. But this can break some existing firewall rulesets. And that should be discuissed -- we do not need the total breakage due to out changes. And you're right: the best way for this alternative is to leave the current behaviour as the compatibility sysctl that is turned off by default and move to the filtering on the physical interfaces by default. No problem, but skilled network people that are using FreeBSD as the bridge for VLANs should say if they are happy with it. I think it is acceptable for if_bridge(4) to know about the existence of VLAN interfaces and to deal with them accordingly as a special case, because Spanning Tree is specified differently in the case where VLANs are present. Therefore it is not unreasonable for if_bridge(4) to be looking at VLAN headers in the mbuf chain. As such I think the behaviour Andrew Thompson and I were discussing off list should be made the default: that is, the first 802.1q VLAN header is stripped off and turned into an M_VLANTAG before being passed to other consumers in the stack. The presence of M_VLANTAG makes it very easy to see that a frame was received with a VLAN header without involving vlan(4) and reduces the amount of 802.1q specific code across Layer 2 subsystems. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Bruce, Tue, Mar 13, 2007 at 11:36:54AM +, Bruce M. Simpson wrote: In short: M_PROMISC exists to easily identify frames which were received promiscuously, to prevent infinite recursion, and to simplify code which needs to re-enter ether_input(). M_PROMISC is a flag introduced by NetBSD into their ethernet input path to deal with the case where an entity in the network stack needs to receive frames promiscuously, without necessarily passing those frames to the upper layers e.g. IPv4. It is not documented; the code is the documentation in this instance. It is cleared when an mbuf chain is passed to another entity which may consume the frame in that mbuf chain, in case the entity re-enters ether_input() with the same mbuf chain for local delivery (e.g. bridge, netgraph, vlan). Got the idea, thanks! I agree with you. That is why I patched if_bridge once again to enable the pfil hooks for the physical incoming interface. And there are two ways to solve the problem: - to give each VLAN interface the distinct MAC, as Bruce suggested, I didn't suggest this. :-) OK, sorry. - to refuse the logical interfaces completely and to support only physical ones. It is what my very first (and very short) patch did. But this can break some existing firewall rulesets. And that should be discuissed -- we do not need the total breakage due to out changes. And you're right: the best way for this alternative is to leave the current behaviour as the compatibility sysctl that is turned off by default and move to the filtering on the physical interfaces by default. No problem, but skilled network people that are using FreeBSD as the bridge for VLANs should say if they are happy with it. I think it is acceptable for if_bridge(4) to know about the existence of VLAN interfaces and to deal with them accordingly as a special case, because Spanning Tree is specified differently in the case where VLANs are present. Therefore it is not unreasonable for if_bridge(4) to be looking at VLAN headers in the mbuf chain. I see your point, but all if_bridge can do with the VLAN header is to identify the VLAN ID. But this will not help us in the case of multiple identical MAC addresses, when the physical input interface is not the L2 destination. Just because all we can do with the VLAN tag is to identify the physical incoming VLAN. But it is already passed to the bridge_input in the form of 'ifp'. Or I am missing some point here? As such I think the behaviour Andrew Thompson and I were discussing off list should be made the default: that is, the first 802.1q VLAN header is stripped off and turned into an M_VLANTAG before being passed to other consumers in the stack. So you want the if_vlan to mark the packet with the ETHERTYPE_VLAN (in-band VLAN tag) with M_VLANTAG? The presence of M_VLANTAG makes it very easy to see that a frame was received with a VLAN header without involving vlan(4) and reduces the amount of 802.1q specific code across Layer 2 subsystems. Sure. But it seems to be unusable for our bug. Though maybe I am wrong. -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Bruce, good day! Tue, Mar 06, 2007 at 04:00:10PM +, Bruce M. Simpson wrote: Eygene Ryabinkin wrote: I am awfully sorry, but you're seem to be mistaken: Thanks for clarifying this. That'll be because I didn't read if_bridge that far. ;^) In my original message I was just looking at if_ethersubr.c. I need to make sure any changes which are made to if_bridge to deal with vlan problems are incorporated into bms_netdev so that after I commit M_PROMISC, it does the right thing. OK, after discuissing the problem for a while, Roman Kurakin (rik@) decided to modify my patch: it will not just blindly rewriting the interface in the mbuf, but will apply an extra check for the physical incoming interface before checking the other bridge members. So it will hopefully do no harm to anything that was worked before and will cure the problem I spotted. Speaking about vlan problems: the original problem is to do something with VLAN interfaces only because they are sharing the MAC of their physical parent. The problem itself is not VLAN-specific -- if there will be two physical interfaces with the same MACs and they will be bridged, the problem will still be here. Will drop you a letter when the patch will be ready. -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Hi, Eygene Ryabinkin wrote: Speaking about vlan problems: the original problem is to do something with VLAN interfaces only because they are sharing the MAC of their physical parent. The problem itself is not VLAN-specific -- if there will be two physical interfaces with the same MACs and they will be bridged, the problem will still be here. I see this also. What would be good is if there was a way to record additional MAC addresses for each ifnet, in addition to the if_lladdr member. This would cut down the cruft in ether_input(), if_bridge(4) and possibly also carp(4). For network cards with more than one perfect hash filter entry in the hardware, programming these into the card would *perhaps* be more efficient when trying to achieve line rate with gigabit and beyond. This would most likely require an ABI change. The VLAN handling problem doesn't go away; we will still need to check if a bridge member is a VLAN interface because we can't uniquely key off the MAC as you point out. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
On Mon, Mar 12, 2007 at 09:36:43AM +, Bruce M. Simpson wrote: Hi, Eygene Ryabinkin wrote: Speaking about vlan problems: the original problem is to do something with VLAN interfaces only because they are sharing the MAC of their physical parent. The problem itself is not VLAN-specific -- if there will be two physical interfaces with the same MACs and they will be bridged, the problem will still be here. I see this also. What would be good is if there was a way to record additional MAC addresses for each ifnet, in addition to the if_lladdr member. This would cut down the cruft in ether_input(), if_bridge(4) and possibly also carp(4). For network cards with more than one perfect hash filter entry in the hardware, programming these into the card would *perhaps* be more efficient when trying to achieve line rate with gigabit and beyond. This would most likely require an ABI change. The VLAN handling problem doesn't go away; we will still need to check if a bridge member is a VLAN interface because we can't uniquely key off the MAC as you point out. Guys, excuse me, but I still fail to see how the case of VLANs' sharing a single MAC differs from the case of several physical interfaces with the same MAC from the POV of a bridge. A bridge can have no own MAC addresses at all, it plays with foreign MAC addresses only. Therefore I can't see why our bridge code needs to know local MAC addresses, let alone why it fails when they're the same. Could you give me a hint? Thanks! -- Yar ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Yar, good day. Mon, Mar 12, 2007 at 02:20:56PM +0300, Yar Tikhiy wrote: On Mon, Mar 12, 2007 at 09:36:43AM +, Bruce M. Simpson wrote: Eygene Ryabinkin wrote: Speaking about vlan problems: the original problem is to do something with VLAN interfaces only because they are sharing the MAC of their physical parent. The problem itself is not VLAN-specific -- if there will be two physical interfaces with the same MACs and they will be bridged, the problem will still be here. I see this also. What would be good is if there was a way to record additional MAC addresses for each ifnet, in addition to the if_lladdr member. This would cut down the cruft in ether_input(), if_bridge(4) and possibly also carp(4). For network cards with more than one perfect hash filter entry in the hardware, programming these into the card would *perhaps* be more efficient when trying to achieve line rate with gigabit and beyond. This would most likely require an ABI change. The VLAN handling problem doesn't go away; we will still need to check if a bridge member is a VLAN interface because we can't uniquely key off the MAC as you point out. Guys, excuse me, but I still fail to see how the case of VLANs' sharing a single MAC differs from the case of several physical interfaces with the same MAC from the POV of a bridge. It does not differ at all, you're right. VLAN case is just an illustration for the problem, but the problem itself is not limited to a VLAN interfaces. A bridge can have no own MAC addresses at all, it plays with foreign MAC addresses only. Therefore I can't see why our bridge code needs to know local MAC addresses, let alone why it fails when they're the same. Could you give me a hint? Thanks! This is a different point. The bridge wants to know about bridge members MACs just because it should catch the packets that are destined to the bridge members. It is the only way for an L2 thing that is operating in the promiscious mode. For our case (when MACs are the same): I think that rik@ has explained it rather good, so you should read his message once again. Perhaps, we can talk about this off-list and in Russian, if you prefer. -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Bruce, Mon, Mar 12, 2007 at 09:36:43AM +, Bruce M. Simpson wrote: Speaking about vlan problems: the original problem is to do something with VLAN interfaces only because they are sharing the MAC of their physical parent. The problem itself is not VLAN-specific -- if there will be two physical interfaces with the same MACs and they will be bridged, the problem will still be here. I see this also. What would be good is if there was a way to record additional MAC addresses for each ifnet, in addition to the if_lladdr member. This would cut down the cruft in ether_input(), if_bridge(4) and possibly also carp(4). Am I understand you correctly that you want to see many MAC addresses on the physical interface that is 'hosting' VLAN interfaces and each VLAN if will have its own MAC? For network cards with more than one perfect hash filter entry in the hardware, programming these into the card would *perhaps* be more efficient when trying to achieve line rate with gigabit and beyond. Sure, but for the commodity hardware it will be the overhead to go into the promiscious mode and to filter the packets by multiple MACs. Or you see any other way to do it on the software. This would most likely require an ABI change. The VLAN handling problem doesn't go away; we will still need to check if a bridge member is a VLAN interface because we can't uniquely key off the MAC as you point out. We're not checking if the interface member is a VLAN interface. We just do the generic checks for the incoming interface. rik@ will send the patch today, at least he just promised me ;)) The only problem that will stay here after our patch is that the pfil will see the 'logical' interface, not the physical one. And if the logical destination interface will have non-unique MAC, then we will again fail to get the right one. But this problem is only pfil-specific: the stack will get the packet in any way, but pfil will get the wrong interface (see rik's long mail in this thread). I did the patch that enables the pfil to see the physical incoming interface for the bridge (it adds one more pfil pass for the packet). I will raise the topic when our patch will be committed (or will not be committed ;((). -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: [...] We're not checking if the interface member is a VLAN interface. We just do the generic checks for the incoming interface. rik@ will send the patch today, at least he just promised me ;)) Here it is. I'll check it for compilation this evening and I hope Eygene will be able to put it in a production for testings. I've found one more strange place in the code. Probably it is not a problem but I do not understand smth. How common the situation that we get our own packets on the bridge? Probably we could do some optimization around this case ... From the original commit (in OpenBSD IIRC) that adds this check it is not clear why it was added. rik Index: if_bridge.c === RCS file: /home/ncvs/src/sys/net/if_bridge.c,v retrieving revision 1.94 diff -u -r1.94 if_bridge.c --- if_bridge.c 9 Mar 2007 19:34:55 - 1.94 +++ if_bridge.c 12 Mar 2007 12:50:45 - @@ -2121,42 +2121,62 @@ return (m); } +#ifdef DEV_CARP +# define OR_CARP_CHECK_WE_ARE_DST(iface) \ + || ((iface)-if_carp \ +carp_forus((iface)-if_carp, eh-ether_dhost)) +# define OR_CARP_CHECK_WE_ARE_SRC(iface) \ + || ((iface)-if_carp \ +carp_forus((iface)-if_carp, eh-ether_shost)) +#else +# define OR_CARP_CHECK_WE_ARE_DST(iface) +# define OR_CARP_CHECK_WE_ARE_SRC(iface) +#endif + +#define GRAB_OUR_PACKETS(iface) \ + if ((iface)-if_type == IFT_GIF) \ + continue; \ + /* It is destined for us. */ \ + if (memcmp(IF_LLADDR((iface)), eh-ether_dhost, ETHER_ADDR_LEN) == 0 \ + OR_CARP_CHECK_WE_ARE_DST((iface)) \ + ) { \ + if (bif-bif_flags IFBIF_LEARNING)\ + (void) bridge_rtupdate(sc, \ + eh-ether_shost, bif, 0, IFBAF_DYNAMIC);\ + m-m_pkthdr.rcvif = iface; \ + BRIDGE_UNLOCK(sc); \ + return (m); \ + } \ + \ + /* We just received a packet that we sent out. */ \ + if (memcmp(IF_LLADDR((iface)), eh-ether_shost, ETHER_ADDR_LEN) == 0 \ + OR_CARP_CHECK_WE_ARE_SRC((iface)) \ + ) { \ + BRIDGE_UNLOCK(sc); \ + m_freem(m); \ + return (NULL); \ + } + /* * Unicast. Make sure it's not for us. +* +* Give a chance for ifp at first priority. This will help when the +* packet comes through the interface like VLAN's with the same MACs +* on several interfaces from the same bridge. This also will save +* some CPU cycles in case the destination interface and the input +* interface (eq ifp) are the same. */ - LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { - if (bif2-bif_ifp-if_type == IFT_GIF) - continue; - /* It is destined for us. */ - if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, - ETHER_ADDR_LEN) == 0 -#ifdef DEV_CARP - || (bif2-bif_ifp-if_carp -carp_forus(bif2-bif_ifp-if_carp, eh-ether_dhost)) -#endif - ) { - if (bif-bif_flags IFBIF_LEARNING) - (void) bridge_rtupdate(sc, - eh-ether_shost, bif, 0, IFBAF_DYNAMIC); - m-m_pkthdr.rcvif = bif2-bif_ifp; - BRIDGE_UNLOCK(sc); - return (m); - } + do { GRAB_OUR_PACKETS(ifp) } while (0); - /* We just received a packet that we sent out. */ - if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_shost, - ETHER_ADDR_LEN) == 0 -#ifdef DEV_CARP - || (bif2-bif_ifp-if_carp -carp_forus(bif2-bif_ifp-if_carp, eh-ether_shost)) -#endif - ) { - BRIDGE_UNLOCK(sc); - m_freem(m); - return (NULL); - } + /* Now check the all bridge members. */ + LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { + GRAB_OUR_PACKETS(bif2-bif_ifp) } +#undef OR_CARP_CHECK_WE_ARE_DST +#undef OR_CARP_CHECK_WE_ARE_SRC +#undef GRAB_OUR_PACKETS + /* Perform the bridge forwarding function. */
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: This is a different point. The bridge wants to know about bridge members MACs just because it should catch the packets that are destined to the bridge members. It is the only way for an L2 thing that is operating in the promiscious mode. Correct. For our case (when MACs are the same): I think that rik@ has explained it rather good, so you should read his message once again. Perhaps, we can talk about this off-list and in Russian, if you prefer. The problem isn't going to go away. It will get bigger when 802.3ad trunking is introduced. Andrew Thompson is currently working on this code. It may also affect the 802.11 code in future, which as you know is layered around Ethernet. It would be good to have a well thought out architectural solution for this problem. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Yar Tikhiy wrote: Guys, excuse me, but I still fail to see how the case of VLANs' sharing a single MAC differs from the case of several physical interfaces with the same MAC from the POV of a bridge. A bridge can have no own MAC addresses at all, it plays with foreign MAC addresses only. Therefore I can't see why our bridge code needs to know local MAC addresses, let alone why it fails when they're the same. Could you give me a hint? Thanks! A few points: 1. A bridge *does* have a MAC address; it is automatically assigned one to participate in IEEE 802.1d Spanning Tree. 2. In the case where 802.3ad trunking is implemented, the same Ethernet address may be used by multiple physical interfaces. 3. As Eygene explained well: there are a number of consumers of Ethernet frames in the stack. As if_bridge may potentially be passed mbuf chains containing packets for these consumers first, it must examine the destination address to determine if it should claim the packet or not. Finally, because of the above points, the Ethernet destination address cannot be regarded as a unique key in the bridge code, or indeed the general Ethernet path, for where packets should be relayed in the stack as a whole. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
On Mon, Mar 12, 2007 at 01:26:13PM +, Bruce M. Simpson wrote: Yar Tikhiy wrote: Guys, excuse me, but I still fail to see how the case of VLANs' sharing a single MAC differs from the case of several physical interfaces with the same MAC from the POV of a bridge. A bridge can have no own MAC addresses at all, it plays with foreign MAC addresses only. Therefore I can't see why our bridge code needs to know local MAC addresses, let alone why it fails when they're the same. Could you give me a hint? Thanks! A few points: 1. A bridge *does* have a MAC address; it is automatically assigned one to participate in IEEE 802.1d Spanning Tree. Well, I'd say it *can* have a MAC address if it wants to participate in STP. 2. In the case where 802.3ad trunking is implemented, the same Ethernet address may be used by multiple physical interfaces. 3. As Eygene explained well: there are a number of consumers of Ethernet frames in the stack. As if_bridge may potentially be passed mbuf chains containing packets for these consumers first, it must examine the destination address to determine if it should claim the packet or not. Finally, because of the above points, the Ethernet destination address cannot be regarded as a unique key in the bridge code, or indeed the general Ethernet path, for where packets should be relayed in the stack as a whole. But why are we relying solely on the Ethernet destination address? Each frame was received via a particular interface, which is recorded in mbuf's recvif. As the frame moves between levels of abstraction, such as a physical interface, vlan, bridge, recvif can change, but at each level the pointer to an entity in the previous level should be enough, shouldn't it? E.g., if several vlan interfaces are bridged, if_bridge shouldn't need to know which physical interfaces are used by the vlans. OTOH, it can know which particular vlan the frame came through, although vlan MACs can be the same. -- Yar ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Yar, 2. In the case where 802.3ad trunking is implemented, the same Ethernet address may be used by multiple physical interfaces. 3. As Eygene explained well: there are a number of consumers of Ethernet frames in the stack. As if_bridge may potentially be passed mbuf chains containing packets for these consumers first, it must examine the destination address to determine if it should claim the packet or not. Finally, because of the above points, the Ethernet destination address cannot be regarded as a unique key in the bridge code, or indeed the general Ethernet path, for where packets should be relayed in the stack as a whole. But why are we relying solely on the Ethernet destination address? Probably because if_bridge is written for Ethernet, 802.11 and may be some other 802 interfaces: - DESCRIPTION The if_bridge driver creates a logical link between two or more IEEE 802 networks that use the same (or ``similar enough'') framing format. For example, it is possible to bridge Ethernet and 802.11 networks together, but it is not possible to bridge Ethernet and Token Ring together. - Each frame was received via a particular interface, which is recorded in mbuf's recvif. As the frame moves between levels of abstraction, such as a physical interface, vlan, bridge, recvif can change, but at each level the pointer to an entity in the previous level should be enough, shouldn't it? Excuse me, but are we talking about the problem that is cured by our patch, or about some general points? If about the former, then this problem shows up only for the packet that is destined for the local interface at the L2. And the pfil gots the wrong interface name due to the bug. E.g., if several vlan interfaces are bridged, if_bridge shouldn't need to know which physical interfaces are used by the vlans. OTOH, it can know which particular vlan the frame came through, although vlan MACs can be the same. And who is saying that if_bridge should need to know about the underlying (parent) interface for the VLAN? The word 'physical' that we use here denotes the VLAN interface in which the packet showed up at ether_input. And the word 'logical' means the interface that the L2 packet is destined for. Perhaps it is the source of confusion? -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
On Mon, Mar 12, 2007 at 05:38:11PM +0300, Eygene Ryabinkin wrote: Yar, 2. In the case where 802.3ad trunking is implemented, the same Ethernet address may be used by multiple physical interfaces. 3. As Eygene explained well: there are a number of consumers of Ethernet frames in the stack. As if_bridge may potentially be passed mbuf chains containing packets for these consumers first, it must examine the destination address to determine if it should claim the packet or not. Finally, because of the above points, the Ethernet destination address cannot be regarded as a unique key in the bridge code, or indeed the general Ethernet path, for where packets should be relayed in the stack as a whole. But why are we relying solely on the Ethernet destination address? Probably because if_bridge is written for Ethernet, 802.11 and may be some other 802 interfaces: - DESCRIPTION The if_bridge driver creates a logical link between two or more IEEE 802 networks that use the same (or ``similar enough'') framing format. For example, it is possible to bridge Ethernet and 802.11 networks together, but it is not possible to bridge Ethernet and Token Ring together. - The IEEE standards don't prevent us from keeping the pointer to the receive interface and using it to identify the interface unambiguously. That's what I meant. Each frame was received via a particular interface, which is recorded in mbuf's recvif. As the frame moves between levels of abstraction, such as a physical interface, vlan, bridge, recvif can change, but at each level the pointer to an entity in the previous level should be enough, shouldn't it? Excuse me, but are we talking about the problem that is cured by our patch, or about some general points? If about the former, then this problem shows up only for the packet that is destined for the local interface at the L2. And the pfil gots the wrong interface name due to the bug. A patch is unlikely to be correct if it's based on wrong assumptions. E.g., if several vlan interfaces are bridged, if_bridge shouldn't need to know which physical interfaces are used by the vlans. OTOH, it can know which particular vlan the frame came through, although vlan MACs can be the same. And who is saying that if_bridge should need to know about the underlying (parent) interface for the VLAN? The word 'physical' that we use here denotes the VLAN interface in which the packet showed up at ether_input. And the word 'logical' means the interface that the L2 packet is destined for. Perhaps it is the source of confusion? Quite likely. Even pfil is confused. ;^) As I've managed to figure out finally, the physical interface (in this discussion) is the interface the L2 packet actually came from, and the logical one just bears the MAC address equal to that in the destination field of the packet. The problem is that we cannot determine the logical interface reliably in the presence of interfaces sharing the same MAC address. No hacks can help us with that. Assume that a host has two physical interfaces, say, em0 and em1, with different MAC addresses. We set up a few vlans on the former and a few vlans on the latter, and then bridge all vlans together. Now an Ethernet packet comes via, say, em0.7, with its destination MAC address equal to that of em1 (and its vlans). Which of em1.* vlans would you logically assign the packet to, and why? I'm afraid there is a serious flaw in the very notion of such a logical interface. If it's true, we should start by admitting that the support for logical interfaces should be a side hack for compatibility, and not something that can live forever on the main code path. -- Yar ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Yar Tikhiy wrote: On Mon, Mar 12, 2007 at 05:38:11PM +0300, Eygene Ryabinkin wrote: Yar, 2. In the case where 802.3ad trunking is implemented, the same Ethernet address may be used by multiple physical interfaces. 3. As Eygene explained well: there are a number of consumers of Ethernet frames in the stack. As if_bridge may potentially be passed mbuf chains containing packets for these consumers first, it must examine the destination address to determine if it should claim the packet or not. Finally, because of the above points, the Ethernet destination address cannot be regarded as a unique key in the bridge code, or indeed the general Ethernet path, for where packets should be relayed in the stack as a whole. But why are we relying solely on the Ethernet destination address? Probably because if_bridge is written for Ethernet, 802.11 and may be some other 802 interfaces: - DESCRIPTION The if_bridge driver creates a logical link between two or more IEEE 802 networks that use the same (or ``similar enough'') framing format. For example, it is possible to bridge Ethernet and 802.11 networks together, but it is not possible to bridge Ethernet and Token Ring together. - The IEEE standards don't prevent us from keeping the pointer to the receive interface and using it to identify the interface unambiguously. That's what I meant. Each frame was received via a particular interface, which is recorded in mbuf's recvif. As the frame moves between levels of abstraction, such as a physical interface, vlan, bridge, recvif can change, but at each level the pointer to an entity in the previous level should be enough, shouldn't it? Excuse me, but are we talking about the problem that is cured by our patch, or about some general points? If about the former, then this problem shows up only for the packet that is destined for the local interface at the L2. And the pfil gots the wrong interface name due to the bug. A patch is unlikely to be correct if it's based on wrong assumptions. Read my very long email again. The model used by the bridge to deliver the packet for our host is not wrong. E.g., if several vlan interfaces are bridged, if_bridge shouldn't need to know which physical interfaces are used by the vlans. OTOH, it can know which particular vlan the frame came through, although vlan MACs can be the same. And who is saying that if_bridge should need to know about the underlying (parent) interface for the VLAN? The word 'physical' that we use here denotes the VLAN interface in which the packet showed up at ether_input. And the word 'logical' means the interface that the L2 packet is destined for. Perhaps it is the source of confusion? Quite likely. Even pfil is confused. ;^) As I've managed to figure out finally, the physical interface (in this discussion) is the interface the L2 packet actually came from, and the logical one just bears the MAC address equal to that in the destination field of the packet. The problem is that we cannot determine the logical interface reliably in the presence of interfaces sharing the same MAC address. No hacks can help us with that. Assume that a host has two physical interfaces, say, em0 and em1, with different MAC addresses. We set up a few vlans on the former and a few vlans on the latter, and then bridge all vlans together. Now an Ethernet packet comes via, say, em0.7, with its destination MAC address equal to that of em1 (and its vlans). Which of em1.* vlans would you logically assign the packet to, and why? This problem was described in my very long e-mail. And yes it can not be fixed. Only if we will try to assign the packet to every interfaces in bridge with the same MAC, until the rules for the one allow this packet. This is too heavy solution. But if we can't fix the all sides of this problem it doesn't mean we shouldn't try to fix one that possible. rik I'm afraid there is a serious flaw in the very notion of such a logical interface. If it's true, we should start by admitting that the support for logical interfaces should be a side hack for compatibility, and not something that can live forever on the main code path. ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Yar, good day. Probably because if_bridge is written for Ethernet, 802.11 and may be some other 802 interfaces: - DESCRIPTION The if_bridge driver creates a logical link between two or more IEEE 802 networks that use the same (or ``similar enough'') framing format. For example, it is possible to bridge Ethernet and 802.11 networks together, but it is not possible to bridge Ethernet and Token Ring together. - The IEEE standards don't prevent us from keeping the pointer to the receive interface and using it to identify the interface unambiguously. That's what I meant. OK, no problem: we can keep the actual incoming interface in the mbuf. Each frame was received via a particular interface, which is recorded in mbuf's recvif. As the frame moves between levels of abstraction, such as a physical interface, vlan, bridge, recvif can change, but at each level the pointer to an entity in the previous level should be enough, shouldn't it? Excuse me, but are we talking about the problem that is cured by our patch, or about some general points? If about the former, then this problem shows up only for the packet that is destined for the local interface at the L2. And the pfil gots the wrong interface name due to the bug. A patch is unlikely to be correct if it's based on wrong assumptions. Yes, it is based on the wrong assumptions that were made about 3-4 years ago in the NetBSD. And the real problem here is if we want to leave the current behaviour of locally destined packets or we want completely different thing. We asked in the list if someone uses the current behaviour, but no replies were received yet. And who is saying that if_bridge should need to know about the underlying (parent) interface for the VLAN? The word 'physical' that we use here denotes the VLAN interface in which the packet showed up at ether_input. And the word 'logical' means the interface that the L2 packet is destined for. Perhaps it is the source of confusion? Quite likely. Even pfil is confused. ;^) As I've managed to figure out finally, the physical interface (in this discussion) is the interface the L2 packet actually came from, and the logical one just bears the MAC address equal to that in the destination field of the packet. The problem is that we cannot determine the logical interface reliably in the presence of interfaces sharing the same MAC address. No hacks can help us with that. Sure. And that is why all switches that can bear the IP on their interfaces have distinct MACs for each interface or/and the only one interface can have the IP. And that is why I am going to add the paragraph to the if_bridge(4) describing the current situation and giving advice on the setting IP for the bridge members and the bridge itself. Will provide the patch in a day or two. Assume that a host has two physical interfaces, say, em0 and em1, with different MAC addresses. We set up a few vlans on the former and a few vlans on the latter, and then bridge all vlans together. Now an Ethernet packet comes via, say, em0.7, with its destination MAC address equal to that of em1 (and its vlans). Which of em1.* vlans would you logically assign the packet to, and why? This problem was described in my very long e-mail. And yes it can not be fixed. Only if we will try to assign the packet to every interfaces in bridge with the same MAC, until the rules for the one allow this packet. This is too heavy solution. But if we can't fix the all sides of this problem it doesn't mean we shouldn't try to fix one that possible. See bms_netdev, it's rather promising: with it, we won't have to do duplicate checks for the destination MAC address. Namely see lines 642-682 of //depot/user/bms/netdev/sys/net/if_ethersubr.c#9. The things may need some moving around, but all code is already there. Then the bridge_input code will be able to make use of M_PROMISC to see if it must consume the packet or just update its forwarding table. I tried to understand this, because Bruce already gave me a patch, but I am a bit stupid: I do not see how M_PROMISC that is cleared unconditionally before BRIDGE_INPUT will help us to identify the right interface. As I see now, the BRIDGE_INPUT is called once from if_ethersubr.c, once from if_gif.c and once from ng_ether.c: http://fxr.watson.org/fxr/ident?i=BRIDGE_INPUT So there is no distinct code paths that can allow BRIDGE_INPUT to modify its behaviour based on the M_PROMISC flag. But I feel that I am wrong in some place and missing some discuission on the M_PROMISC. Can anyone point me to the right place? So all the tangled if()s inside LIST_FOREACH() will be gone completely from bridge_input(). But we still need to see if we want to consume the packet by the bridge or it members or to do forwarding. Am I missing
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Andrew Thompson wrote: On Tue, Mar 06, 2007 at 08:22:16PM +0300, Roman Kurakin wrote: Ok, since no one want to provide an explanation I'll to do it myself. ... I suggest to fix this problem in the other way, by checking if the physical interface is the dst interface by MAC. Eq if we got packet from Ci, it will be market as received from Ci, not from Cj. Yes it will add double checking for this interface it is not the dst with some probability, but will optimize the case the dst is the current one cause we will not check the list. This will keep the old behaviour eq case 1 and will do the same trick for cases like VLANs. Here my variant of the patch: I think this is probably the best way to do it. I have only been loosely following this thread due to other stuff going on. +/* Give a chance for ifp at first priority. This will help in case we + * the packet comes through the interface with VLAN's and the same + * MACs on several interfaces in a bridge. Also will save some circles + * in case dst interface is the physical input interface (eq ifp). + */ +if (ifp-if_type == IFT_GIF ^^^ is this check right? It was taken from original code. In the rest part of course there is no bif2, but ifp. I'll plane to make a macro as suggested by Eygene. This code shouldn't be in a separate function for sure. So code will look like #define somemacro somemacro(ifp) LIST_FOREACH() somemacro(bif2-bif_ifp) rik ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
+/* Give a chance for ifp at first priority. This will help in case we + * the packet comes through the interface with VLAN's and the same + * MACs on several interfaces in a bridge. Also will save some circles + * in case dst interface is the physical input interface (eq ifp). + */ +if (ifp-if_type == IFT_GIF ^^^ is this check right? No, it should read if (ifp-if_type == IFT_GIF) continue; if (memcmp(IF_LLADDR(.))) { ... } -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
On Tue, Mar 06, 2007 at 08:22:16PM +0300, Roman Kurakin wrote: Ok, since no one want to provide an explanation I'll to do it myself. ... I suggest to fix this problem in the other way, by checking if the physical interface is the dst interface by MAC. Eq if we got packet from Ci, it will be market as received from Ci, not from Cj. Yes it will add double checking for this interface it is not the dst with some probability, but will optimize the case the dst is the current one cause we will not check the list. This will keep the old behaviour eq case 1 and will do the same trick for cases like VLANs. Here my variant of the patch: I think this is probably the best way to do it. I have only been loosely following this thread due to other stuff going on. +/* Give a chance for ifp at first priority. This will help in case we + * the packet comes through the interface with VLAN's and the same + * MACs on several interfaces in a bridge. Also will save some circles + * in case dst interface is the physical input interface (eq ifp). + */ +if (ifp-if_type == IFT_GIF ^^^ is this check right? + (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, +ETHER_ADDR_LEN) == 0 +#ifdef DEV_CARP +|| (bif2-bif_ifp-if_carp + carp_forus(bif2-bif_ifp-if_carp, eh-ether_dhost)) +#endif +)) { +if (bif-bif_flags IFBIF_LEARNING) +(void) bridge_rtupdate(sc, +eh-ether_shost, bif, 0, IFBAF_DYNAMIC); +m-m_pkthdr.rcvif = ifp; +BRIDGE_UNLOCK(sc); +return (m); +} I will be keen to see your final patch. Andrew ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: I am awfully sorry, but you're seem to be mistaken: Thanks for clarifying this. That'll be because I didn't read if_bridge that far. ;^) In my original message I was just looking at if_ethersubr.c. I need to make sure any changes which are made to if_bridge to deal with vlan problems are incorporated into bms_netdev so that after I commit M_PROMISC, it does the right thing. if_bridge calls the ipfw directly only for the L2 filtering (when the net.link.bridge.ipfw is set to 1). This is processed by the block in if_bridge just above to the 'ipfwpass' label. In bms_netdev, the behaviour of ether_demux() is unchanged. ip_dn_claim_rule() is called to determine if there is an IPFW (usually dummynet) rule for the input frame at ethernet level, if-and-only-if net.link.ether.ipfw is non-zero. I just committed some comments to clarify this and styled it the same as the check in ether_output_frame(). However -- the IPFW check in ether_demux() is *skipped* in bms_netdev if M_PROMISC is set. This is because we might drop packets which are destined for vlan_input() which flow in because the interface is IFF_PROMISC. Strictly speaking this bends the rules of dummynet, because if you have frames coming in due to promiscuous mode, which the rest of the stack doesn't expect, they won't be filtered by Dummynet pipes. But the L3 filtering is done fully by the pfil hooks, as I understand the code. Moreover, I am using 'pf' in my case, not the ipfw. Yes, this is always the case for the upper layers. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Ok, since no one want to provide an explanation I'll to do it myself. Lets assume that we have two interfaces that are joined to bridge. I'll call them as A and B. Both has a distinct MACs. Now we have two cases for behaviour of filtering. The first case that we will behave like real hub between the physical interfaces and its virtual logical representation. The packet will arise on logical interface for which it is intended for (according to dst MAC). That is how it is implemented now. So now we can filter packets treating dst interface as incoming, but not the interfaces it comes through physically. The second variant to do visa versa, e q filter packets according interfaces they physically come in, and do not take in to account the dst MAC. Both variant have bad sides and good sides. Both are not wrong from the filtering point of view. So I do not want to discuss which one is correct. Now about the problem. Lets assume that we also have a C interfaces, but with VLANs or anything that will bring the same situation. I'll call VLANs C1,C2...CN. Now we can't implement the first case without a problems, cause all Cx will have the same MAC, MAC of the C interface. In current implementation we will take the first interface on the list, which would be the last added to the bridge. This problem could be fixed. Be patient, I'll describe all cases, but not at once. Read till the end of the letter. If I understand right the Eygene's patch solves problem by introducing the second behaviour. It is not quite good cause it will change the old known behaviour. Here is the patch itself: --- if_bridge.c.orig Fri Mar 2 18:23:56 2007 +++ if_bridge.c Sat Mar 3 05:04:38 2007 @@ -2122,7 +2122,11 @@ LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { if (bif2-bif_ifp-if_type == IFT_GIF) continue; -/* It is destined for us. */ +/* It is destined for us. We should not rely on the + * found interface's MAC as the interface identifier, + * because vlanX interfaces are sharing their MAC + * with the parent. Moreover, we do know the interface + * the packet is coming from. So we're using it. */ if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, ETHER_ADDR_LEN) == 0 #ifdef DEV_CARP @@ -2133,7 +2137,7 @@ if (bif-bif_flags IFBIF_LEARNING) (void) bridge_rtupdate(sc, eh-ether_shost, bif, 0, IFBAF_DYNAMIC); -m-m_pkthdr.rcvif = bif2-bif_ifp; +m-m_pkthdr.rcvif = ifp; BRIDGE_UNLOCK(sc); return (m); } I suggest to fix this problem in the other way, by checking if the physical interface is the dst interface by MAC. Eq if we got packet from Ci, it will be market as received from Ci, not from Cj. Yes it will add double checking for this interface it is not the dst with some probability, but will optimize the case the dst is the current one cause we will not check the list. This will keep the old behaviour eq case 1 and will do the same trick for cases like VLANs. Here my variant of the patch: +/* Give a chance for ifp at first priority. This will help in case we + * the packet comes through the interface with VLAN's and the same + * MACs on several interfaces in a bridge. Also will save some circles + * in case dst interface is the physical input interface (eq ifp). + */ +if (ifp-if_type == IFT_GIF + (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, +ETHER_ADDR_LEN) == 0 +#ifdef DEV_CARP +|| (bif2-bif_ifp-if_carp + carp_forus(bif2-bif_ifp-if_carp, eh-ether_dhost)) +#endif +)) { +if (bif-bif_flags IFBIF_LEARNING) +(void) bridge_rtupdate(sc, +eh-ether_shost, bif, 0, IFBAF_DYNAMIC); +m-m_pkthdr.rcvif = ifp; +BRIDGE_UNLOCK(sc); +return (m); +} LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { if (bif2-bif_ifp-if_type == IFT_GIF) continue; /* It is destined for us. */ if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, ETHER_ADDR_LEN) == 0 #ifdef DEV_CARP || (bif2-bif_ifp-if_carp carp_forus(bif2-bif_ifp-if_carp, eh-ether_dhost)) #endif ) { if (bif-bif_flags IFBIF_LEARNING) (void) bridge_rtupdate(sc, eh-ether_shost, bif, 0, IFBAF_DYNAMIC); m-m_pkthdr.rcvif = bif2-bif_ifp; BRIDGE_UNLOCK(sc);
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Roman, good day! Lets assume that we have two interfaces that are joined to bridge. I'll call them as A and B. Both has a distinct MACs. Now we have two cases for behaviour of filtering. The first case that we will behave like real hub between the physical interfaces and its virtual logical representation. The packet will arise on logical interface for which it is intended for (according to dst MAC). That is how it is implemented now. So now we can filter packets treating dst interface as incoming, but not the interfaces it comes through physically. Yes, I've finally got the idea, thanks! The second variant to do visa versa, e q filter packets according interfaces they physically come in, and do not take in to account the dst MAC. Both variant have bad sides and good sides. Both are not wrong from the filtering point of view. So I do not want to discuss which one is correct. I can add only one thing: I am already did the patch to implement filtering on the physical incoming interface as well as on the logical one. It is working quite well for the week on a rather busy filtering bridge that is serving around 60 hosts. The additional behaviour is controlled by a new sysctl, so it can be easily switched on and off. Now about the problem. Lets assume that we also have a C interfaces, but with VLANs or anything that will bring the same situation. I'll call VLANs C1,C2...CN. Now we can't implement the first case without a problems, cause all Cx will have the same MAC, MAC of the C interface. In current implementation we will take the first interface on the list, which would be the last added to the bridge. This problem could be fixed. Be patient, I'll describe all cases, but not at once. Read till the end of the letter. If I understand right the Eygene's patch solves problem by introducing the second behaviour. It is not quite good cause it will change the old known behaviour. Here is the patch itself: --- if_bridge.c.orig Fri Mar 2 18:23:56 2007 +++ if_bridge.c Sat Mar 3 05:04:38 2007 @@ -2122,7 +2122,11 @@ LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { if (bif2-bif_ifp-if_type == IFT_GIF) continue; -/* It is destined for us. */ +/* It is destined for us. We should not rely on the + * found interface's MAC as the interface identifier, + * because vlanX interfaces are sharing their MAC + * with the parent. Moreover, we do know the interface + * the packet is coming from. So we're using it. */ if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, ETHER_ADDR_LEN) == 0 #ifdef DEV_CARP @@ -2133,7 +2137,7 @@ if (bif-bif_flags IFBIF_LEARNING) (void) bridge_rtupdate(sc, eh-ether_shost, bif, 0, IFBAF_DYNAMIC); -m-m_pkthdr.rcvif = bif2-bif_ifp; +m-m_pkthdr.rcvif = ifp; BRIDGE_UNLOCK(sc); return (m); } I suggest to fix this problem in the other way, by checking if the physical interface is the dst interface by MAC. Eq if we got packet from Ci, it will be market as received from Ci, not from Cj. Yes it will add double checking for this interface it is not the dst with some probability, but will optimize the case the dst is the current one cause we will not check the list. This will keep the old behaviour eq case 1 and will do the same trick for cases like VLANs. Here my variant of the patch: +/* Give a chance for ifp at first priority. This will help in case we + * the packet comes through the interface with VLAN's and the same + * MACs on several interfaces in a bridge. Also will save some circles + * in case dst interface is the physical input interface (eq ifp). + */ +if (ifp-if_type == IFT_GIF + (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, +ETHER_ADDR_LEN) == 0 +#ifdef DEV_CARP +|| (bif2-bif_ifp-if_carp + carp_forus(bif2-bif_ifp-if_carp, eh-ether_dhost)) +#endif +)) { +if (bif-bif_flags IFBIF_LEARNING) +(void) bridge_rtupdate(sc, +eh-ether_shost, bif, 0, IFBAF_DYNAMIC); +m-m_pkthdr.rcvif = ifp; +BRIDGE_UNLOCK(sc); +return (m); +} LIST_FOREACH(bif2, sc-sc_iflist, bif_next) { if (bif2-bif_ifp-if_type == IFT_GIF) continue; /* It is destined for us. */ if (memcmp(IF_LLADDR(bif2-bif_ifp), eh-ether_dhost, ETHER_ADDR_LEN) == 0 #ifdef DEV_CARP || (bif2-bif_ifp-if_carp
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Eygene Ryabinkin wrote: Will try to understand if it will cure my problem, thanks! Attaching my patch, just in case if freebsd gnats will be down ;)) Thanks for this. It looks like Andrew may be in a better position to say if this fix should go in or not. It is possible that if bridge changes the ifp and that the frame should be forwarded locally, i.e. to the upper protocol layers, that ifp should also be updated in ether_input() (as NetBSD does) to make sure that the later checks are against the updated ifp. I have just changed this behaviour in p4 bms_netdev. Please try to test with this code. If you can't access p4, then I can extract an updated patch though this will take longer. This should help to eliminate the need for DEV_CARP compile-time conditionals in if_bridge(4). Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Hi, Eygene Ryabinkin wrote: Sure, I can test it, but then I need to know what problems are cured by your patch, or I just should watch if it will not break something. My concern is that I want to make sure that all these changes to the ether_input path work OK together. The M_PROMISC flag is set further down when it's determined that a frame flowing into ether_input() was received promiscuously, and therefore Layer 3 protocols (e.g. IP) may not want to see it. In NetBSD, after if_bridge is given a chance to claim an input frame, the ifp may be changed if the bridge needs to forward locally. In my case if_bridge drops off the packet because firewall fails to recognize the packet as good: the interface that is passed to a pfil_hooks is bad (I mean not the one expected). The ifp which your patch changes is that of the mbuf chain when bridge_input determines it is not for the bridge, but should be forwarded locally. The patch forces a locally forwarded frame to have the same ifp as it had when it came into bridge_input. I can foresee problems if the same Ethernet destination address exists on multiple bridge member interfaces. The latest version of p4 bms_netdev now updates the cached ifp in ether_input() if bridge_input() changed it in this way. NetBSD consistently uses pfil_hooks for the if_bridge *and* ether_input paths, FreeBSD currently calls ipfw directly for ether_input, which may make a difference to the behaviour which you are seeing with VLANs. Not understanding if_bridge fully, or the coupling of ipfw with if_ethersubr.c, I would hope that Andrew and others have more to say on this. Will try to see if your patch makes any difference for the 7-CURRENT, but I have no system at hand to test it, sorry. The patch is extracted from p4 therefore it should apply against CURRENT. I haven't updated the patch yet, the latest code is in p4. We won't be able to eliminate the DEV_CARP checks in this spin. I did exchange an idea with Andrew late last night whereby a list of addresses other than ether_dhost is maintained for each ifnet. Input paths then check this in addition to or instead of ether_dhost. I've added this to the Wiki. I've been working particularly hard lately so I'm not 100% clear. Thanks, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Bruce, In my case if_bridge drops off the packet because firewall fails to recognize the packet as good: the interface that is passed to a pfil_hooks is bad (I mean not the one expected). The ifp which your patch changes is that of the mbuf chain when bridge_input determines it is not for the bridge, but should be forwarded locally. The patch forces a locally forwarded frame to have the same ifp as it had when it came into bridge_input. I can foresee problems if the same Ethernet destination address exists on multiple bridge member interfaces. The code in the if_bridge.c changes the ifp anyway: I am just setting the ifp to a more sane value. NetBSD consistently uses pfil_hooks for the if_bridge *and* ether_input paths, FreeBSD currently calls ipfw directly for ether_input, which may make a difference to the behaviour which you are seeing with VLANs. I am awfully sorry, but you're seem to be mistaken: if_bridge calls the ipfw directly only for the L2 filtering (when the net.link.bridge.ipfw is set to 1). This is processed by the block in if_bridge just above to the 'ipfwpass' label. But the L3 filtering is done fully by the pfil hooks, as I understand the code. Moreover, I am using 'pf' in my case, not the ipfw. Not understanding if_bridge fully, or the coupling of ipfw with if_ethersubr.c, I would hope that Andrew and others have more to say on this. I am too ;)) Thank you! -- Eygene ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]
Re: kern/109815: wrong interface identifier at pfil_hooks for vlans + if_bridge
Hi, I haven't seen your patch, can you point me at it off-list? Thanks. Eygene Ryabinkin wrote: I traced the current if_bridge.c behaviour to the NetBSD's if_bridge.c 1.9. This was the first version in that the firewall hooks were introduced. And the assumtion that the MAC identifies the physical interfaces was used in this first version. And a question: can anyone say if my patch will break some known good behaviour and if the current behaviour of if_bridge is based on some logic I am currently failing to understand. I would greatly appreciate it if you could look at the combined M_PROMISC and 802.1p patch, which rewrites ether_input() significantly. It sounds like the issues you are having with vlans and bridges may potentially be fixed by this patch, or that the fix may be incorporated more easily with this patch. In NetBSD, after if_bridge is given a chance to claim an input frame, the ifp may be changed if the bridge needs to forward locally. M_PROMISC is used to indicate that a frame was received promiscuously, in case ether_input() re-enters itself with the same mbuf chain. Certain consumers of ether_input() need to punch holes in the logic used to detect if a frame was for us or not because they do funky things with Ethernet destination addresses, e.g. carp. Regards, BMS ___ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to [EMAIL PROTECTED]