On Apr 7, 2012, at 6:05 PM, Bruce Dubbs wrote: > Qrux wrote: >> On Apr 6, 2012, at 3:24 PM, Bruce Dubbs wrote: >> >>> Qrux wrote: >>> >>>> 1) Why is ifup bringing up the virtual interface? That is >>>> clearly a service-level responsibility. In fact, in the case of >>>> a bridge, that interface doesn't even exist until you create it >>>> with brctl. What purpose does it serve in ifup? > >>> Sine it it placed after the creation/configuration, it brings up >>> the interface specified and any component interfaces. > >> But why is it in ifup? ifup should not be aware of the bridge >> interface. > > It's not aware of the bridge explicitly. It's just sets whatever > interface and any potential components up.
The point is, ifup should not be setting up the logical interface. That's the job of the service. ifup should handle the physical interface. The existing released versions confuse the logical with the physical interface. It used them interchangeably, until bridge showed up. Then, another var got introduced (INTERFACES) and the confusion got worse, because the distinction was never made clear, and the scripts referred to the "wrong" variable. Ifup should load the ifconfig file. And, if it sees PHYS, it should use its value; if it doesn't, it should set PHYS to IFACE. Then, it should *ONLY EVER* refer to PHYS in the body of the script, and never to IFACE. >>>> 2) Why does ifup manage any routing at all (including gw)? >>>> That's a service-level issue. > >>> Sort of the same thing. It prevents needing the code in multiple >>> locations. > >> It should only be in one location: ipv4-static. It's an IP >> configuration parameter. Not a physical link parameter. > > For now, it could be in either place, but I think it gives more > flexibility for future services. What does "flexibility" have to do with cleanly separating functionality? The way this discussion is going, it sounds like you'd rather just fold all the service stuff into ifup. What happened to confining the problem space to ifup/ifdown, ipv4-static, dhcp, and bridge (and possibly virtual NICs)? >>>> 3) Why does bridge handle setting IP_FORWARD? Why isn't that in >>>> ipv4-static? Bridging shouldn't care about IP issues like >>>> routing, and that's the wrong place to set it. > >>> It's needed for passing packets from the outside to a bridged >>> device. It's there for convenience. If IP_FORWARD isn't specified, >>> then nothing happens. > >> I'm not exactly sure how your bridge configurations look like. Even >> without my virtualization setup, when I have a bridge on br0 that >> enslaves eth0, I don't need forwarding to see "output" packets. Is >> there something strange that the KVM stuff does to the default >> bridging configuration? > > It was suggested in the documentation I read. This is not a technical reason. What did this documentation say, specifically, about bridges needing IP forwarding? >> Secondly, (again with the why), IP_FORWARD is a system-wide setting. >> Why is bridge handling that? Bridges should not be aware of >> IP_FORWARD. I would stand behind your idea that IP forwarding should >> go in sysctl.conf. > > Again, it was there for convenience. If needed by the bridge, then all > the network configuration items are in one location. Forwarding has nothing to do with bridging, other than the fact that they are networking functions. IP forwarding is not a bridge setting. They are completely orthogonal. Bridging allows a machine to span two segments of the same network. The machine could happen to be both at the same time. But neither is required for the other to work. It seems more and more like this is some KVM requirement that's influencing the way you're seeing how bridges work. A bridge does not require forwarding. If KVM does, that's a separate issue. I can set up a bridge without any of my virtualization stuff, and there's never any need of forwarding. Separately, the direction you seem to be going is to fold everything up into one script. If you want to do that, then we don't need to have this discussion. But, as it currently stands, which I agree with, there *are* separate scripts because ifup should not be instrumented to know everything about every service. So, since they're already separated, keep them separated in a way that makes sense. >> The point is, this running theme of parameters being applied in >> inappropriate places is the main motivation behind my scripts. >> Frankly, they are not that different. The existing ones--including >> this round of changes--do not, and seem to proliferate the surprising >> behavior of settings parameters in unexpected places. > > There are only ifup/ifdown and the services they call. You can't really > understand ifup without the services and vice versa. They are not long > scripts. Surprise is not an issue. ifup is only doing four things > beyond simple error checking: > > Create/configure the intrerface > Set the interface up > If requested, set the interface MTU > If requested, set the interface as the route default > > All this is done in about 25 lines of code, including comments. Yes...If your goal is to condense the scripts into one script, you could make the same argument that the non-boilerplate stuff in each of the services is really one a few lines (validations aside), and you may as well fold them into ifup/ifdown. If you want to take that approach, that's fine. But, if the scripts are to be separate, then they should be separated by what they do. An IP gateway is an IP function. I'm not sure of any new ways to say this in a way that would be any more convincing than: "If you want separate scripts, then separate them by logical function." "If you want one script, then make arguments like: 'it's only 25 lines'." Overall, I prefer better logical separation between ifup and the services. I want ifup to do physical stuff (e.g., MTU and setting UP/DOWN), and services to do service stuff (yes, bridge touches the PHYS variable, but in a *service-specific* way). That's a clean mental model to me that's simple to understand. ifup uses the values in PHYS in the body of the script (and sets PHYS to what's in IFACE if PHYS is unspecified). Services use the values in IFACE, and only touch PHYS if absolutely necessary--because ifup cannot know how. An example is enslaving ports to a bridge. I can't describe your goals in a simple way, because you seem to be going for a blend of convenience: * ifup sets gateway, despite an IP gateway being an obvious IP config parameter. * The bridge service sets the system-wide kernel parameter of IP_FORWARD. and completeness * We need to maintain BROADCAST because it's always been there... * ...plus, ip allows it... * ...and we need to keep it, regardless of whether or not it's even valid. * We should validate MTU values--because an RFC says so. Completeness and convenience seem weird juxtaposed like this, and make even less sense as a organizing principle in the context of what I though had been the agreed upon problem scope: ifup/ifdown, ipv4-static, dhcp, and bridge. In fact, they're not just weird--they're opposed. If convenience is the goal, then roll up all the services into ifup. In fact, that seems to be the logical end of your point that nothing can be surprising, regardless of which script it appears in, because they're all short. OTOH, if completeness is the goal, why insist you want to avoid complexity? You claim it's more convenient to throw IP_FORWARD into bridge, and IPv4 routing into ifup. There's no point to a technical discussion in the context those kinds of statements. Convenience is a matter of taste; it's not a technical consideration. If an issue were technically neutral, then, sure, do what's convenient. Like the name of the variable PHYS. That's technically neutral. And, that's resolved like this: "You're the committer; you call it what you want." I chose PHYS because it was short--and tells you exactly what it is--it's the physical interface. But, if you want to call it: BRIDGE_SPECIFIC_ATTACHED_COMPONENT_INTERFACE then by all means, go for it. If you want to validate MTU values, go ahead; it obviously doesn't hurt, but it doesn't really help, either. I don't feel strongly about either; and I shouldn't. But, when the committer starts discussing convenience, why have a technical discussion? I've given my technical disagreements (from a sw-eng perspective of keeping components as cleanly decoupled as possible) , and shared my framework for how I think the problem should be viewed (ifup does physical interface, services do logical interface). It should--but it can't--compete with "convenience". >>>> (Another minor point...Why specify BROADCAST? Isn't it unusual >>>> to have an address/prefix that didn't produce the right broadcast >>>> address.) > >>> An old habit. It used to be always required. Leaving it doesn't >>> hurt anything. >> >> It's completely superfluous. Yes, it *can* hurt. A wrongly >> configured broadcast address can bork your IP configuration. If it's >> entirely unneeded, don't you think it's better to leave it out? If >> the logic to look for it is not there, it can't be misconfigured. >> It's entirely determined by the IP address and the PREFIX. If the >> scripts look at PREFIX instead of a classic netmask, then it should >> also avoid BROADCAST. >> >> Look at it another way. Taking the BROADCAST-handling logic out does >> not hurt ifconfig scripts that still have it in; it's just completely >> ignored. People can get around to removing that extraneous parameter >> when they need it. > > BROADCAST has been in the script since the script was first put in svn > in 2004. Perhaps is should be removed. I'd like some other opinions. There's a lot of back-and-forth between you wanting to keep things simple (i.e., for the 95% use-case) and then somewhat arbitrarily wanting to include things for completeness. Is there anyone out there--that doesn't do hardware NIC testing or is a kernel/iptables developer--that sets a netmask that doesn't agree with broadcast? Is this even a valid IP configuration? >>>> 6) Also, do we just dislike PHYS as a variable name? That seems >>>> preferable to two variables with similar and somewhat confusing >>>> names (IFACE vs INTERFACES). > >>> It's a personal preference. The only place INTERFACES makes any >>> sense is on a bridge. Most users will never use that. > >> Even if it's rarely used--which I don't necessarily agree >> with--should it be confusing? If it's your scenario (that it's >> rarely used), then we have lots of flexibility to choose a meaningful >> and less ambiguous variable name. If it's often used, then it should >> *definitely* be less ambiguous. > > OK. I do want to keep IFACE, but I'm willing to change INTERFACES. > What do you suggest. PHYS doesn't seem right to me. How about > COMPONENT_INTERFACES? ATTACHED_INTERFACES? I picked PHYS because it's short, and because it tells the viewer what he needs to know. Whatever is listed is a physical interface. You can be as verbose as you'd like, and you can call it what you like. To me, the question is: "Which variable conveys: 'This is the physical interface.'?" The answer is: "You're the committer. This is a technically neutral issue. Call it whatever you want." I'm just going to keep typing PHYS because it's shorter and reasonably descriptive. >>>> Stuff like ifup handling gateways, bridge handling IP-related >>>> sysctls, and ifup bringing up bridge interfaces all seem >>>> misplaced. > >>> The alternative is to replicate some functionality in multiple >>> service scripts. > >> Where is this replication? In fact, I'm trying to remove replication >> as well as surprising parameter setting in unexpected scripts. > > There is potential replication if a new service script is developed. How? I thought we were restricting the problem space to ifup/ifdown, ipv4-static, dhcp, and bridge. I feel like we're on different pages again. At one point you said to try to keep things more simple and just handle bridge, ipv4-static, and dhcp (perhaps with virtual NICs), and I agreed and said that that was fine--we should focus on getting the 95% done. Now you're talking about new services that don't exist, and trying to maintain stuff like IP forwarding. >>> I could put the IP_FORWARD in the bridge script, but a user might >>> well want to bring up eth0 and eth2 and enable IP_FORWARD. Of >>> course, that could be also done in either syscyl.conf or in the >>> iptables configuration script. > >> I would agree if you're saying that IP_FORWARD is a system parameter, >> and should be set in a system-wide fashion, and not in a way that >> implies a relationship to a per-logical-interface. Enabling IP >> forwarding in ifconfig wrongly implies it's a per-logical-interface >> setting. It's very much a system-wide parameter, and doesn't really >> make sense in ifconfig files. Consider how it would interact with >> iptables if setting the sysctl happens only if a certain ifconfig >> scripts gets reached. > > The iptables script could set it also, but since the network boot script > comes after iptables, the last one takes priority. There's nothing to > prevent a user from creating a S99local bootscript and setting it there > either. This isn't about where the user *could* put it. It's about whether or not it's sensible to put it into ifconfig. The fact that I didn't remove IP_FORWARD from bridge is not the same as tacit approval. I just made the minimal about of edits to get my idea across while keeping the diff small. If I was editing for a "finished draft", there are quite a few things I'd remove. I thought the point of this discussion was to focus the scope on the existing scripts (+- bridge) and talk about how it would look best for the 95% use-case. Now we're talking about future services and forwarding. I still strongly believe that this link between forwarding and bridging is a weird side effect of running KVM. >> In fact, if we stick by your "KISS" suggestion, IP forwarding >> shouldn't even get treatment here. It's another "advanced" feature >> that people can enable on their own. IP forwarding is orthogonal to >> bridging. > > It's providing an easy option. We also have PEER in ipv4-static, but > I've never used it. I think it is needed for KVM, so I set it in the > bridge service. KVM is KVM. KVM is not bridging. If KVM is a "service", so to speak, then you should have a /lib/lsb/kvm-setup, and it does forwarding (or whatever KVM needs). Your ifconfig should have a line like this for the KVM-related interfaces: SERVICE="bridge ipv4-static kvm-setup" Better yet, move IP_FORWARD somewhere else entirely. I didn't put IP_FORWARD into bridge. I just hadn't gotten around to removing it from bridge yet, because at that time, it wasn't affecting anything. Now, I would definitely cut it out. >>>> It's good to take time to look at this, but can you reframe this >>>> in terms of the problems you're solving? AFAIK, there was only >>>> one remaining issue to look at, which is how to properly support >>>> virtual NICS. I thought I had resolved the issues with MTU, >>>> multiple PHYS per bridge, and cleanly separating the >>>> service/physical logic issues. It just seems like a lot of >>>> changes here are pushing the wrong logic into the wrong scripts. > >>> I'd like to keep the scripts as simple as possible. What are the >>> circumstances where more than one physical interface is needed for >>> a bridge? How many of our users need such a capability? >>> >>> I'm trying to provide an alternate solution to the ticket you >>> created. I was uncomfortable with your solution. > >> I don't have any issue with your discomfort, but I'd like to >> understand the technical objection(s). > > In ifup you only set the MTU if you do a CHECK_LINK. The interface does > not need to be up to set the MTU. Simple, and it sounds like you changed this already. > The CHECK_LINK operation controls whether to set the interface up or > not. This is only useful for a bridge where the bridge device has not > yet been created. If the procedure for setting the interface up is > delayed to after bridge creation, CHECK_LINK is not required at all. Why is CHECK_LINK even needed, ever, at all? ifup should just bring up the physical interfaces, and leave everything else to the services. In the event that PHYS and IFACE have the same value, then setting UP on the logical interface up is a side-effect of setting UP on the physical one. But we should stop confusing the two. > Setting the GATEWAY in ipv4-static doesn't make more sense than setting > it in ifup. The only real need for ipv4-static is to set the ip address > for the interface. ...I can only say that an IP gateway is an IP parameter. It should be set in ipv4-static. Otherwise, why have separate service scripts at all? Why put IP logic in ifup? ifup should handle the physical interface; services should handle service-specific logic. IP parameters are IP-specific. That should go into ipv4-static. > bridge created the bridge device and adds interface devices to it. > Setting the bridge up there and setting the ethx interfaces up in ifup > didn't make sense to me. This is the mental model I use: * ifup handles physical interface parameters (UP/DOWN, MTU) * services handle service-specific parameters (e.g., IP, PREFIX) What is confusing? When a service is brought up, it can think: "Okay--the physical interface is up, regardless of whether I'm going to further configure them (as in a bridge) or whether I used them directly (as in a vanilla ipv4-static). Oh--and I'm taken down, someone else (probably my caller) will take the physical interface down; that's not my concern." This is a very simple and straightforward mental model. > Your version of bridge creates the bridge, sets it up, > adds ethx interfaces, and sets ip_forward. I just moved the 'set up' > to ifup so the bridge and ethx devices can all be brought up together. IIRC, you added the IP_FORWARD stuff. I just hadn't gotten around to taking it out. I think you see ifup as the locus of control. I understand your mental model, in so far as I can only infer that you'd like everything to be rolled up into one script. Your comments point down the direction that the service scripts are one-liners, and that we may as well roll everything up into ifup. I'm still not sure if you understand mine. I think it's simple: ifup does physical, and srvices do logical. That may not be clear because the current scripts confuse the two and use them interchangeably. PHYS is not IFACE. IFACE is not PHYS. PHYS is not a bridge-specific thing. It just so happens that with bridges, you expose the fact that they are different. One is a physical interface (eth0). The other is logical (br0). Services should only deal with logical interfaces, and they should touch physical interfaces in service-specific ways. ifup should only deal with physical interface, and it should never touch the logical interfaces. If you're going to split up responsibility between services and ifup, then do so cleanly. It just so happens that, often (sometimes?) the logical interface is the physical one. But, that's not always the case. And, that's just a shortcut someone took, that happened to work in most vanilla setups. While bridge is the first one to make the distinction painfully obvious, I strongly suspect more complex setups like PPP, tunneling, and bonding will also highlight the distinction. > In ipv4-static, I just moved the GATEWAY code to be after the 'set up' > because the GATEWAY code failed if the device was down. > >> It seems that in trying to keep things simple, you're spreading logic >> into strange places: ifup handles some IP parameters > > which ones? You just said this. Gateway. >> , physical link parameters, > > Yes, mtu Right. Clean. > and also brings up bridges interfaces. Wrong. Bridge interfaces are logical interfaces. > The name of the program is ifup, as in interface up. I understand that you do not see that physical interfaces are not logical interfaces. This statement: "The name of the program is ifup, as in interface up" is supposed to be significant how? The point is that when ifup returns, it will have brought the interface up. I'm talking about what its functions (i.e., sub-programs) do, and how those interfaces should be decoupled. You keep seeing things from the POV of the caller of ifup. I'm talking about how ifup (and the scripts it calls--which are it's "functions") should be put together. You're giving a sermon about what? How...when ifup finishes successfully, the "interface" should be brought "up"? Just because it's called ifup isn't an adequate explanation of why it partitions its own behavior into sub-scripts. I'm talking about organizing principles for the script and its sub-scripts. You're saying what? That "GCC, as in 'GNU C Compiler' should compile C programs, and not call into other programs."? That "Well, if it's more convenient, throw AST parsing into the preprocessor."? We are not talking about what ifup should do from the POV of the caller. We are talking about how ifup--and the scripts it calls--should be internally organized. >> Then, bridge handles some IP issues, > > which? ip_forward? Your version did that too. The ip_forward code > could easily be brought up to ifup. This is not "my version". Yes, the one I posted with the changes I made also include YOUR changes (including the adding of IP_FORWARD). I did not say that I felt it was all kosher. That's why I invited the original discussion when bridge-utils was brought up long ago. >> but ipv4-static/dhcp also handles IP issues. > > When I look at this, we really only have a couple of differences. There > are only a few lines of code in different sections of what is logically > all one function (ifup/ifdown) and some minor naming issues. It's not just one function. It's a function ifup() that calls other functions called ipv4-static(), dhcp(), bridge(), in various combinations. That is the point of this discussion--how those should be separated. I understand your POV--that ifup() is a single locus of control, but I don't see it that way. If that was the case, why even split up the functionality? My problem space: ifup/ifdown, ipv4-static, dhcp, bridge, virtual NICs. My mental model : ifup -> physical; services -> logical. My goal: working, cleanly decoupled scripts. Your problem space is not clear to me (because you're talking about "future scripts"). The mental model isn't totally clear to me because it seems to go back and forth a bit between convenience and completeness (IP_FORWARD vs BROADCAST and MTU-value-checking). You goal seems to be to put as much as possible into ifup. It's hard to infer what your organizing principles are at the moment. Every time I think we're talking about one thing, the ground seems to shift. I'll have to bow out for now until I have time to spend on the scripts themselves. I just think it ought to be clear that ifup should handle physical interface parameters only, because if it were meant to do more than the services never needed to be decoupled in the first place. OTOH, if that's your plan, to roll everything back up into ifup, then why is this conversation even necessary? Q -- http://linuxfromscratch.org/mailman/listinfo/lfs-dev FAQ: http://www.linuxfromscratch.org/faq/ Unsubscribe: See the above information page